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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

const int MAXN = 1e4 + 10;
const int MAXG = 110;

int n, m;
int x[MAXN], op[MAXN], y[MAXN];
int f[MAXG][MAXG], g[MAXG][MAXG];
bool vis[MAXG];

void dfs(int u) {
  int i, k;
  vis[u] = 1;
  for (i = 1; i <= n; i++)
    if (g[u][i]) {
      if (!vis[i])
        dfs(i);
      for (k = 1; k <= n; k++)
        if (f[i][k])
          f[u][k] = f[k][u] = 1;
    }
}

bool check(int mid) {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      f[i][j] = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++)
      g[i][j] = 0;
    g[i][i] = 1;
  }
  for (int Q = 1; Q <= mid; Q++) {
    int i = x[Q], j = y[Q], ope = op[Q];
    if (ope == 1)
      g[i][j] = 1;
    else if (ope == 2)
      g[i][j] = g[j][i] = 1;
    else if (ope == 4)
      f[i][j] = f[j][i] = 1;
  }
  for (int k = 1; k <= n; k++)
    for (int i = 1; i <= n; i++)
      for (int j = 1; j <= n; j++)
        if (g[i][k] && g[k][j])
          g[i][j] = 1;

  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= n; i++)
    if (!vis[i])
      dfs(i);

  for (int Q = 1; Q <= mid; Q++) {
    int i = x[Q], j = y[Q], ope = op[Q];
    if (ope == 3) {
      if (f[i][i] && f[j][j])
        return false;
      if (g[i][j] && g[j][i])
        return false;
    } else if (ope == 5) {
      if (f[i][j] || f[j][i] || f[i][i] || f[j][j])
        return false;
    }
  }
  return true;
}

int main() {
  while (~scanf("%d%d", &n, &m) && (n + m)) {
    for (int i = 1; i <= m; i++)
      scanf("%d%d%d", &op[i], &x[i], &y[i]);
    int l = 1, r = m, ans = 0;
    while (l <= r) {
      int mid = l + r >> 1;
      if (check(mid)) {
        ans = mid;
        l = mid + 1;
      } else
        r = mid - 1;
    }
    printf("%d\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

const int maxn = 100 + 2;
vector<int> a[maxn], b[maxn], qu[2];
bool have[maxn][maxn];
bool visit[2][maxn];
int fa[maxn];
int times, p[maxn], ST, n;

struct edge {
  int flag, u, v;
} e[10000];

void dfs3(int u, bool visit[], vector<int> &qu) {
  visit[u] = 1;
  qu.push_back(u);
  for (int i = 0; i < a[u].size(); i++)
    if (!visit[a[u][i]]) {
      dfs3(a[u][i], visit, qu);
    }
}

void add(int u, int v) {
  a[u].push_back(v);
  b[v].push_back(u);
  memset(visit, 0, sizeof(visit));
  qu[0].clear();
  dfs3(v, visit[0], qu[0]);
  for (int i = 1; i <= n; i++)
    if (have[u][i])
      for (int j = 0; j < qu[0].size(); j++)
        have[i][qu[0][j]] = have[qu[0][j]][i] = 1;
}

void dfs1(int u, bool visit[]) {
  visit[u] = 1;
  for (int i = 0; i < a[u].size(); i++)
    if (!visit[a[u][i]]) {
      dfs1(a[u][i], visit);
    }
  p[++times] = u;
}

void dfs2(int u, bool visit[]) {
  visit[u] = 1;
  fa[u] = ST;
  for (int i = 0; i < b[u].size(); i++)
    if (!visit[b[u][i]]) {
      dfs2(b[u][i], visit);
    }
}

bool check(int m) {
  memset(visit, 0, sizeof(visit));
  times = 0;
  ST = 0;
  for (int i = 1; i <= n; i++)
    if (!visit[0][i])
      dfs1(i, visit[0]);
  for (int i = n; i > 0; i--)
    if (!visit[1][p[i]]) {
      ST++;
      dfs2(p[i], visit[1]);
    }
  for (int i = 0; i <= m; i++) {
    if (e[i].flag == 3) {
      // printf("%d %d\\n",fa[ e[i].u],fa[e[i].v]);
      if (fa[e[i].u] == fa[e[i].v])
        return 0;
    } else if (e[i].flag == 4) {
      // printf("have=%d %d %d\\n",e[i].u,e[i].v,have[e[i].u][e[i].v]);
      if (have[e[i].u][e[i].v])
        return 0;
      else {
        bool flagu = 0, flagv = 0;
        for (int j = 1; j <= n; j++) {
          if (have[e[i].u][j])
            flagu = 1;
          if (have[e[i].v][j])
            flagv = 1;
        }
        memset(visit, 0, sizeof(visit));
        qu[0].clear();
        dfs3(e[i].u, visit[0], qu[0]);
        if (visit[0][e[i].v] && flagu)
          return 0;
        qu[0].clear();
        dfs3(e[i].v, visit[1], qu[0]);
        if (visit[1][e[i].u] && flagv)
          return 0;
      }
    }
  }
  return 1;
}

int main() {
  int m;

  while (scanf("%d%d", &n, &m) == 2) {
    if (n == 0 & m == 0)
      break;
    for (int i = 1; i <= n; i++)
      a[i].clear(), b[i].clear();
    memset(have, 0, sizeof(have));
    int ans = -1;
    for (int i = 0; i < m; i++) {
      scanf("%d%d%d", &e[i].flag, &e[i].u, &e[i].v);
      if (ans != -1)
        continue;
      if (e[i].flag == 1)
        add(e[i].u, e[i].v);
      else if (e[i].flag == 2) {
        add(e[i].u, e[i].v);
        add(e[i].v, e[i].u);
      } else if (e[i].flag == 5) {
        memset(visit, 0, sizeof(visit));
        qu[0].clear();
        qu[1].clear();
        dfs3(e[i].u, visit[0], qu[0]);
        dfs3(e[i].v, visit[1], qu[1]);
        for (int i = 0; i < qu[0].size(); i++)
          for (int j = 0; j < qu[1].size(); j++) {
            have[qu[0][i]][qu[1][j]] = have[qu[1][j]][qu[0][i]] = 1;
            // printf("%d %d\\n",qu[0][i],qu[1][j]);
          }
      }
      if (ans == -1 && !check(i))
        ans = i;
    }
    if (ans == -1)
      ans = m;
    printf("%d\\n", ans);
  }
  return 0;
}