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);
    for (P c : C)
      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 (int 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 100010
using namespace std;
const int INF = 1LL << 55;
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); }

class SCC {
public:
  int V, K;                 //????????°, scc??????????????°
  vector<vector<int>> G;    //??°???????????£??\\??????????????¨???
  vector<vector<int>> rG;   //?????????????????????????????°??????
  vector<vector<int>> DAG;  // scc????????°???????????£??\\??????????????¨???
  vector<vector<int>> rDAG; // scc???????????????????????????????????°??????
  vector<int> vs;           //??°?????????????????????
  vector<int> used;         //?????§???????????????
  vector<int> cmp;          //?±????????????£?????????????????????????????????

  void init() {
    G.resize(V);
    rG.resize(V);
    used.resize(V, 0);
    cmp.resize(V, 0);
  }
  SCC() { V = K = -1; }
  SCC(int V) : V(V) { init(); };

  void add_edge(int from, int to) {
    assert(from < V && to < V);
    G[from].push_back(to);
    rG[to].push_back(from);
  }

  void dfs(int v) {
    used[v] = true;
    for (int nx : G[v])
      if (!used[nx])
        dfs(nx);
    vs.push_back(v);
  }

  void rdfs(int v, int k) {
    used[v] = true;
    cmp[v] = k;
    for (int nx : rG[v])
      if (!used[nx])
        rdfs(nx, k);
  }

  int scc(
      bool makeDAG =
          0) { // DAG?????°???????????????????????£??????makeDAG???1?????????
    used.clear();
    used.resize(V, 0);
    vs.clear();
    for (int v = 0; v < V; v++)
      if (!used[v])
        dfs(v);

    used.clear();
    used.resize(V, 0);
    int &k = K = 0;
    for (int i = vs.size() - 1; i >= 0; i--)
      if (!used[vs[i]])
        rdfs(vs[i], k++);

    if (makeDAG)
      DAG = getDAG(G), rDAG = getDAG(rG); // O(ElogE)

    return k;
  }

  vector<vector<int>> getDAG(const vector<vector<int>> &G) {
    assert(K >= 0);
    vector<vector<int>> res(K);
    for (int from = 0; from < V; from++)
      for (int to : G[from])
        if (cmp[from] != cmp[to])
          res[cmp[from]].push_back(cmp[to]);

    for (int i = 0; i < K; i++) {
      sort(res[i].begin(), res[i].end());
      res[i].erase(unique(res[i].begin(), res[i].end()), res[i].end());
    }
    return res;
  }
};

typedef pair<int, int> P;
typedef vector<P> vec;

bool check(vector<vector<int>> &G, int pos, int goal) {
  if (pos == goal)
    return 0;
  for (int to : G[pos])
    if (!check(G, to, goal))
      return 0;
  return 1;
}

bool check(const vec &A, const vec &B, bool a, bool b) {
  int n(301);
  SCC s(n);
  if (!a)
    for (P p : A)
      s.add_edge(p.first, p.second);
  if (!b)
    for (P p : B)
      s.add_edge(p.first, p.second);
  if (s.scc() != n)
    return 0;

  /*
     vector<set<int> > childs(n);
     for(int pos:s.vs)
    for(int to:s.rG[pos]) {
      childs[to].insert(pos);
      for(int c:childs[pos]) childs[to].insert(c);
    }
    if(a) for(P p:A) if(childs[p.first].count(p.second)) return 0;
    if(b) for(P p:B) if(childs[p.first].count(p.second)) return 0;
  */

  vector<P> C;
  if (a)
    for (P p : A)
      C.push_back(p);
  if (b)
    for (P p : B)
      C.push_back(p);
  sort(C.begin(), C.end());
  C.erase(unique(C.begin(), C.end()), C.end());
  for (P p : C)
    if (!check(s.rG, p.second, p.first))
      return 0;
  return 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;
  vector<vec> G;
  G.push_back(vec({P(idx[a], idx[b])}));
  for (int i = 0; i < n; i++) {
    int m;
    cin >> m;
    vec 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++;
      g[j] = P(idx[a], idx[b]);
    }
    G.push_back(g);
  }

  queue<int> Q;
  Q.push(0);
  vector<int> used(n + 1, -1);
  used[0] = 0;
  while (!Q.empty()) {
    int i = Q.front();
    Q.pop();
    for (int j = 0; j <= n; j++) {
      if (i == j || used[j] != -1)
        continue;
      for (int b = 0; b < 2; b++) {
        int a = used[i];
        if (check(G[i], G[j], a, b))
          continue;
        Q.push(j);
        used[j] = !b;
      }
    }
  }

  vector<P> A, B;
  for (int i = 0; i <= n; i++) {
    if (used[i] == 0)
      for (P p : G[i])
        A.push_back(p);
    if (used[i] == 1 || used[i] == -1)
      for (P p : G[i])
        B.push_back(p);
  }

  int ans = check(A, B, 0, 1);
  cout << (ans ? "Yes" : "No") << endl;

  return 0;
}