Problem p01625 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int D_MAX_V = 30002;
const int D_v_size = 30002;
int V;
const int MAX_V = 30002;
vector<int> G[MAX_V];
int mc[MAX_V];
int match[MAX_V];
bool used[MAX_V];
int ava[MAX_V];
void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
}
bool dfs2(int v) {
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    int u = G[v][i], w = match[u];
    if (!ava[u])
      continue;
    if (w < 0 || !used[w] && dfs2(w)) {
      match[v] = u;
      match[u] = v;
      return true;
    }
  }
  return false;
}
int b_m() {
  int res = 0;
  memset(match, -1, sizeof(match));
  for (int v = 0; v < V; v++) {
    if (match[v] < 0 && ava[v]) {
      memset(used, 0, sizeof(used));
      if (dfs2(v))
        res++;
    }
  }
  return res;
}

int x[5100][5];
int y[5100][5];
vector<pair<int, int>> ad[5100];
vector<int> w[5100];
int dx[7][4] = {{-1, 0, 1, 0}, {-1, 0, 1, 0}, {-1, 0, 0, 1}, {1, 0, 0, -1},
                {0, 0, 1, 1},  {0, 0, 1, 1},  {-1, 0, 1, 2}};
int dy[7][4] = {{0, 0, 0, 1},  {0, 0, 0, -1}, {0, 0, 1, 1}, {0, 0, 1, 1},
                {-1, 0, 0, 1}, {1, 0, 0, -1}, {0, 0, 0, 0}};
int dr[7] = {1, 0, 1, 1, 0, 1, 2};
int ABS(int a) { return max(a, -a); }
pair<int, int> le[25000];
int main() {
  int a;
  while (scanf("%d", &a), a) {
    map<pair<int, int>, int> m;
    map<pair<int, int>, int> m2;
    int sz = 0;
    for (int i = 0; i < a; i++)
      ad[i].clear();
    for (int i = 0; i < a; i++)
      w[i].clear();
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < 3; j++) {
        scanf("%d%d", &x[i][j], &y[i][j]);
        m2[make_pair(x[i][j], y[i][j])] = i;
      }
    }
    int mu = 0;
    int mat = -1;
    for (int i = 0; i < a; i++) {
      int U = 999999;
      int D = -999999;
      int L = 999999;
      int R = -999999;
      for (int j = 0; j < 3; j++) {
        U = min(U, y[i][j]);
        D = max(D, y[i][j]);
        L = min(L, x[i][j]), R = max(R, x[i][j]);
      }
      if (D - U > 2 || R - L > 3)
        continue;
      for (int j = L - 1; j <= R + 1; j++) {
        for (int k = U - 1; k <= D + 1; k++) {
          set<pair<int, int>> S;
          int X = 0;
          int Y = 0;
          for (int l = 0; l < 3; l++) {
            X += x[i][l];
            Y += y[i][l];
            S.insert(make_pair(x[i][l], y[i][l]));
          }
          X += j;
          Y += k;
          S.insert(make_pair(j, k));
          if (S.size() != 4)
            continue;
          bool ok = false;
          int ax = (X + 1) / 4;
          if (X < 0)
            ax = -((ABS(X) + 2) / 4);
          int ay = (Y + 1) / 4;
          if (Y < 0)
            ay = -((ABS(Y) + 2) / 4);
          for (int l = 0; l < 7; l++) {
            bool OK = true;
            if (dr[l] != 2 && ABS(ax + ay) % 2 != dr[l])
              continue;
            for (int ii = 0; ii < 4; ii++) {
              if (S.count(make_pair(ax + dx[l][ii], ay + dy[l][ii])) == 0)
                OK = false;
            }
            if (OK)
              ok = true;
          }
          if (ok) {
            ad[i].push_back(make_pair(j, k));
            if (m.count(make_pair(j, k)) == 0) {
              le[sz] = make_pair(j, k);
              m[make_pair(j, k)] = sz++;
            }
          }
        }
      }
      if (ad[i].size() == 0) {
        mu++;
        mat = i;
      }
    }
    if (mu > 1) {
      printf("Invalid\\n");
      continue;
    }
    V = sz + a;
    for (int i = 0; i < sz + a; i++) {
      G[i].clear();
      ava[i] = 1;
    }
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < ad[i].size(); j++) {
        //		printf("(%d, %d) ",ad[i][j].first,ad[i][j].second);
        add_edge(i + sz, m[ad[i][j]]);
        if (m2.count(ad[i][j])) {
          bool ok = true;
          for (int k = 0; k < w[m2[ad[i][j]]].size(); k++)
            if (w[m2[ad[i][j]]][k] == m[ad[i][j]]) {
              ok = false;
              break;
            }
          if (ok)
            w[m2[ad[i][j]]].push_back(m[ad[i][j]]);
        }
      }
      // printf("\\n");
    }
    for (int i = 0; i < sz; i++) {
      if (m2.count(le[i]))
        ava[i] = 0;
    }
    int now = b_m();
    if (now == a) {
      printf("Valid\\n");
      continue;
    }
    if (now < a - 4) {
      printf("Invalid\\n");
      continue;
    }
    vector<int> sp;
    for (int i = 0; i < a; i++)
      if (match[i + sz] == -1)
        sp.push_back(i);
    vector<int> can;

    for (int i = 0; i < a; i++) {
      if (mu && mat != i)
        continue;
      ava[sz + i] = 0;
      int rev = -1;
      int mtc = now;
      for (int j = 0; j < sz + a; j++)
        mc[j] = match[j];
      if (~match[sz + i]) {
        mtc--;
        rev = match[sz + i];
        match[match[sz + i]] = -1;
        match[sz + i] = -1;
      }
      for (int j = 0; j < w[i].size(); j++) {
        ava[w[i][j]] = 1;
      }
      for (int j = 0; j < sp.size(); j++) {
        if (sp[j] == i)
          continue;
        memset(used, 0, sizeof(used));
        if (dfs2(sp[j] + sz)) {
          mtc++;
        }
      }
      if (mtc == a - 1)
        can.push_back(i);
      for (int j = 0; j < sp.size(); j++) {
        if (~match[sp[j] + sz]) {
          match[match[sp[j] + sz]] = -1;
          match[sp[j] + sz] = -1;
        }
      }
      ava[sz + i] = 1;
      if (~rev) {
        match[rev] = sz + i;
      }
      match[sz + i] = rev;
      for (int j = 0; j < w[i].size(); j++) {
        if (~match[w[i][j]]) {
          match[match[w[i][j]]] = -1;
          match[w[i][j]] = -1;
        }
        ava[w[i][j]] = 0;
      }
      for (int j = 0; j < sz + a; j++)
        match[j] = mc[j];
    }
    if (can.size()) {
      printf("Remove\\n");
      for (int i = 0; i < can.size(); i++)
        printf("%d\\n", can[i] + 1);
    } else
      printf("Invalid\\n");
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int D_MAX_V = 30002;
const int D_v_size = 30002;
struct D_wolf {
  int t, c, r;
  D_wolf() { t = c = r = 0; }
  D_wolf(int t1, int c1, int r1) {
    t = t1;
    c = c1;
    r = r1;
  }
};
vector<D_wolf> D_G[D_MAX_V];
int D_level[D_MAX_V];
int D_iter[D_MAX_V];
int now;
void add_edge(int from, int to, int cap) {
  D_G[from].push_back(D_wolf(to, cap, D_G[to].size()));
  D_G[to].push_back(D_wolf(from, 0, D_G[from].size() - 1));
}
void D_bfs(int s) {
  for (int i = 0; i < D_v_size; i++)
    D_level[i] = -1;
  queue<int> Q;
  D_level[s] = 0;
  Q.push(s);
  while (Q.size()) {
    int v = Q.front();
    Q.pop();
    for (int i = 0; i < D_G[v].size(); i++) {
      if (D_G[v][i].c > 0 && D_level[D_G[v][i].t] < 0) {
        D_level[D_G[v][i].t] = D_level[v] + 1;
        Q.push(D_G[v][i].t);
      }
    }
  }
}
int D_dfs(int v, int t, int f) {
  if (v == t)
    return f;
  for (; D_iter[v] < D_G[v].size(); D_iter[v]++) {
    int i = D_iter[v];
    if (D_G[v][i].c > 0 && D_level[v] < D_level[D_G[v][i].t]) {
      int d = D_dfs(D_G[v][i].t, t, min(f, D_G[v][i].c));
      if (d > 0) {
        D_G[v][i].c -= d;
        D_G[D_G[v][i].t][D_G[v][i].r].c += d;
        return d;
      }
    }
  }
  return 0;
}
int max_flow(int s, int t) {
  int flow = 0;
  for (;;) {
    D_bfs(s);
    if (D_level[t] < 0)
      return flow;
    for (int i = 0; i < D_v_size; i++)
      D_iter[i] = 0;
    int f;
    while ((f = D_dfs(s, t, 99999999)) > 0) {
      flow += f;
    }
  }
  return 0;
}
void add(int u, int v, int s, int t) {
  for (int i = 0; i < D_G[u].size(); i++) {
    if (D_G[u][i].t == v) {
      D_G[u][i].c++;
    }
  }
}
int n;
char vis[35100];
int dfs(int a, int b) {
  if (a == b)
    return 1;
  vis[a] = 1;
  for (int i = 0; i < D_G[a].size(); i++) {
    if (D_G[a][i].c && !vis[D_G[a][i].t]) {
      if (dfs(D_G[a][i].t, b)) {
        D_G[a][i].c--;
        D_G[D_G[a][i].t][D_G[a][i].r].c++;
        return 1;
      }
    }
  }
  return 0;
}
void del(int u, int v, int s, int t) {
  for (int i = 0; i < D_G[u].size(); i++) {
    if (D_G[u][i].t == v) {
      if (D_G[u][i].c) {
        D_G[u][i].c--;
        return;
      }
      memset(vis, 0, n);
      if (dfs(u, v)) {
        D_G[v][D_G[u][i].r].c--;
        return;
      }
      now--;
      D_G[v][D_G[u][i].r].c--;
      memset(vis, 0, n);
      dfs(t, v);
      memset(vis, 0, n);
      dfs(u, s);
      return;
    }
  }
}
int x[5100][5];
int y[5100][5];
vector<pair<int, int>> ad[5100];
vector<int> w[5100];
int dx[7][4] = {{-1, 0, 1, 0}, {-1, 0, 1, 0}, {-1, 0, 0, 1}, {1, 0, 0, -1},
                {0, 0, 1, 1},  {0, 0, 1, 1},  {-1, 0, 1, 2}};
int dy[7][4] = {{0, 0, 0, 1},  {0, 0, 0, -1}, {0, 0, 1, 1}, {0, 0, 1, 1},
                {-1, 0, 0, 1}, {1, 0, 0, -1}, {0, 0, 0, 0}};
int dr[7] = {1, 0, 1, 1, 0, 1, 2};
int ABS(int a) { return max(a, -a); }
pair<int, int> le[25000];
int main() {
  int a;
  while (scanf("%d", &a), a) {
    map<pair<int, int>, int> m;
    map<pair<int, int>, int> m2;
    int sz = 0;
    for (int i = 0; i < a; i++)
      ad[i].clear();
    for (int i = 0; i < a; i++)
      w[i].clear();
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < 3; j++) {
        scanf("%d%d", &x[i][j], &y[i][j]);
        m2[make_pair(x[i][j], y[i][j])] = i;
      }
    }
    int mu = 0;
    int mat = -1;
    for (int i = 0; i < a; i++) {
      int U = 999999;
      int D = -999999;
      int L = 999999;
      int R = -999999;
      for (int j = 0; j < 3; j++) {
        U = min(U, y[i][j]);
        D = max(D, y[i][j]);
        L = min(L, x[i][j]), R = max(R, x[i][j]);
      }
      if (D - U > 2 || R - L > 3)
        continue;
      for (int j = L - 1; j <= R + 1; j++) {
        for (int k = U - 1; k <= D + 1; k++) {
          set<pair<int, int>> S;
          int X = 0;
          int Y = 0;
          for (int l = 0; l < 3; l++) {
            X += x[i][l];
            Y += y[i][l];
            S.insert(make_pair(x[i][l], y[i][l]));
          }
          X += j;
          Y += k;
          S.insert(make_pair(j, k));
          if (S.size() != 4)
            continue;
          bool ok = false;
          int ax = (X + 1) / 4;
          if (X < 0)
            ax = -((ABS(X) + 2) / 4);
          int ay = (Y + 1) / 4;
          if (Y < 0)
            ay = -((ABS(Y) + 2) / 4);
          for (int l = 0; l < 7; l++) {
            bool OK = true;
            if (dr[l] != 2 && ABS(ax + ay) % 2 != dr[l])
              continue;
            for (int ii = 0; ii < 4; ii++) {
              if (S.count(make_pair(ax + dx[l][ii], ay + dy[l][ii])) == 0)
                OK = false;
            }
            if (OK)
              ok = true;
          }
          if (ok) {
            ad[i].push_back(make_pair(j, k));
            if (m.count(make_pair(j, k)) == 0) {
              le[sz] = make_pair(j, k);
              m[make_pair(j, k)] = sz++;
            }
          }
        }
      }
      if (ad[i].size() == 0) {
        mu++;
        mat = i;
      }
    }
    if (mu > 1) {
      printf("Invalid\\n");
      continue;
    }
    int s = sz + a;
    int t = sz + a + 1;
    for (int i = 0; i < t + 1; i++) {
      D_G[i].clear();
      D_level[i] = D_iter[i] = 0;
    }
    for (int i = 0; i < a; i++) {
      add_edge(s, i + sz, 1);
      for (int j = 0; j < ad[i].size(); j++) {
        //		printf("(%d, %d) ",ad[i][j].first,ad[i][j].second);
        add_edge(i + sz, m[ad[i][j]], 1);
        if (m2.count(ad[i][j])) {
          bool ok = true;
          for (int k = 0; k < w[m2[ad[i][j]]].size(); k++)
            if (w[m2[ad[i][j]]][k] == m[ad[i][j]]) {
              ok = false;
              break;
            }
          if (ok)
            w[m2[ad[i][j]]].push_back(m[ad[i][j]]);
        }
      }
      // printf("\\n");
    }
    for (int i = 0; i < sz; i++) {
      if (!m2.count(le[i])) {
        add_edge(i, t, 1);
      } else
        add_edge(i, t, 0);
    }
    now = max_flow(s, t);
    // printf("%d\\n",now);
    if (now == a) {
      printf("Valid\\n");
      continue;
    }
    if (now < a - 4) {
      printf("Invalid\\n");
      continue;
    }
    vector<int> can;
    n = t + 1;
    for (int i = 0; i < a; i++) {
      if (mu && mat != i)
        continue;
      del(s, sz + i, s, t);
      for (int j = 0; j < w[i].size(); j++) {
        add(w[i][j], t, s, t);
      }
      if (w[i].size())
        now += max_flow(s, t);
      if (now == a - 1) {
        can.push_back(i);
      }
      for (int j = 0; j < w[i].size(); j++) {
        del(w[i][j], t, s, t);
      }
      add(s, sz + i, s, t);
      now += max_flow(s, t);
    }
    if (can.size()) {
      printf("Remove\\n");
      for (int i = 0; i < can.size(); i++)
        printf("%d\\n", can[i] + 1);
    } else
      printf("Invalid\\n");
  }
}