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

#include <bits/stdc++.h>
#define int long long
#define N 310
using namespace std;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

typedef pair<int, int> P;
vector<int> G[N];
int g[N][N], can[N][N];
unordered_set<int> childs[N];

void addChild(int pos, int start, int flag = 0) {
  if ((!flag && childs[pos].count(start)))
    return;
  if (pos != start)
    childs[pos].insert(start);
  can[pos][start] = 1;
  can[start][pos] = -1;
  for (int to : G[pos])
    addChild(to, start);
}

void merge(vector<P> &A, vector<P> &B, vector<P> &C, int c) {
  if (c == 1) {
    for (P c : C)
      G[c.second].push_back(c.first), g[c.second][c.first] = 1;
    vector<int> used(N, 0);
    for (P c : C) {
      if (used[c.second]++)
        continue;
      addChild(c.second, c.second, 1);
      for (auto to : childs[c.second]) {
        if (used[to]++)
          continue;
        addChild(c.second, to, 1);
      }
    }
  }

  if (c == -1) {
    for (P c : C)
      B.push_back(c);
    for (P c : C)
      can[c.first][c.second] = -1;
  }
}

signed main() {
  string a, b;
  cin >> a >> b;
  map<string, int> idx;
  int num = 0;
  idx[a] = num++, idx[b] = num++;
  int n;
  cin >> n;

  map<P, unordered_set<int>> DB;
  vector<vector<P>> rule;
  for (int i = 0; i < n; i++) {
    int m;
    cin >> m;
    vector<P> g(m);
    for (int j = 0; j < m; j++) {
      string a, b;
      cin >> a >> b;
      if (!idx.count(a))
        idx[a] = num++;
      if (!idx.count(b))
        idx[b] = num++;
      int na = idx[a], nb = idx[b];
      g[j] = P(na, nb);
      DB[P(na, nb)].insert(i);
    }
    rule.push_back(g);
  }

  vector<P> A({P(idx[a], idx[b])}), B;
  G[idx[b]].push_back(idx[a]);
  childs[idx[a]].insert(idx[b]);

  int K = idx.size();
  vector<int> used(n, 0);
  can[idx[a]][idx[b]] = 1;
  can[idx[b]][idx[a]] = -1;

  int update = 1;
  while (update) {
    update = 0;
    for (int i = 0; i < K; i++)
      for (int j = 0; j < K; j++) {
        if (i == j || can[i][j] == 0 || !DB.count(P(i, j)))
          continue;
        unordered_set<int> &db = DB[P(i, j)];
        for (auto idx : db) {
          if (used[idx]++)
            continue;
          update = 1;
          merge(A, B, rule[idx], can[i][j]);
        }
        DB.erase(P(i, j));
      }
  }
  int ans = 1;
  for (int k = 0; k < K; k++)
    for (int i = 0; i < K; i++)
      for (int j = 0; j < K; j++)
        g[i][j] |= (g[i][k] && g[k][j]);

  for (int i = 0; i < K; i++)
    ans &= (g[i][i] == 0);
  for (P b : B)
    ans &= !childs[b.first].count(b.second);
  cout << (ans ? "Yes" : "No") << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define int long long
#define N 310
using namespace std;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

typedef pair<int, int> P;
vector<int> G[N];
int g[N][N], can[N][N];
unordered_set<int> childs[N];

void addChild(int pos, int start, int flag = 0) {
  if ((!flag && childs[pos].count(start)))
    return;
  if (pos != start)
    childs[pos].insert(start);
  can[pos][start] = 1;
  can[start][pos] = -1;
  for (int to : G[pos])
    addChild(to, start);
}

void merge(vector<P> &A, vector<P> &B, vector<P> &C, int c) {
  if (c == 1) {
    for (P c : C)
      G[c.second].push_back(c.first), g[c.second][c.first] = 1;
    for (P c : C) {
      addChild(c.second, c.second, 1);
      for (auto to : childs[c.second]) {
        addChild(c.second, to, 1);
      }
    }
  }

  if (c == -1) {
    for (P c : C)
      B.push_back(c);
    for (P c : C)
      can[c.first][c.second] = -1;
  }
}

signed main() {
  string a, b;
  cin >> a >> b;
  map<string, int> idx;
  int num = 0;
  idx[a] = num++, idx[b] = num++;
  int n;
  cin >> n;

  map<P, unordered_set<int>> DB;
  vector<vector<P>> rule;
  for (int i = 0; i < n; i++) {
    int m;
    cin >> m;
    vector<P> g(m);
    for (int j = 0; j < m; j++) {
      string a, b;
      cin >> a >> b;
      if (!idx.count(a))
        idx[a] = num++;
      if (!idx.count(b))
        idx[b] = num++;
      int na = idx[a], nb = idx[b];
      g[j] = P(na, nb);
      DB[P(na, nb)].insert(i);
    }
    rule.push_back(g);
  }

  vector<P> A({P(idx[a], idx[b])}), B;
  G[idx[b]].push_back(idx[a]);
  childs[idx[a]].insert(idx[b]);

  int K = idx.size();
  vector<int> used(n, 0);
  can[idx[a]][idx[b]] = 1;
  can[idx[b]][idx[a]] = -1;

  int update = 1;
  while (update) {
    update = 0;
    for (int i = 0; i < K; i++)
      for (int j = 0; j < K; j++) {
        if (i == j || can[i][j] == 0 || !DB.count(P(i, j)))
          continue;
        unordered_set<int> &db = DB[P(i, j)];
        for (auto idx : db) {
          if (used[idx]++)
            continue;
          update = 1;
          merge(A, B, rule[idx], can[i][j]);
        }
        DB.erase(P(i, j));
      }
  }
  int ans = 1;
  for (int k = 0; k < K; k++)
    for (int i = 0; i < K; i++)
      for (int j = 0; j < K; j++)
        g[i][j] |= (g[i][k] && g[k][j]);

  for (int i = 0; i < K; i++)
    ans &= (g[i][i] == 0);
  for (P b : B)
    ans &= !childs[b.first].count(b.second);
  cout << (ans ? "Yes" : "No") << endl;

  return 0;
}