// 全局 int n, m1, m2; // 图 vector<pair<int, int> > edges[NMAX]; // Floyd int dis[NMAX][NMAX]; // Tarjan int low[NMAX], dfn[NMAX], scc[NMAX], sizescc[NMAX]; int dfncnt, scccnt; stack<int> stk;
boolFloyd(int sccno) { memset(dis, INF, sizeof(dis)); for (registerint i = 1; i <= n; i++) if (scc[i] == sccno) { dis[i][i] = 0; for (auto j : edges[i]) dis[i][j.first] = min(dis[i][j.first], j.second); } for (registerint k = 1; k <= n; k++) if (scc[k] == sccno) for (registerint i = 1; i <= n; i++) if (scc[i] == sccno) for (registerint j = 1; j <= n; j++) if (scc[j] == sccno && dis[i][j] > dis[i][k] + dis[k][j]) dis[i][j] = dis[i][k] + dis[k][j]; for (registerint i = 1; i <= n; i++) if (scc[i] == sccno && dis[i][i]) returntrue; returnfalse; }
voidTarjan(int cur) { low[cur] = dfn[cur] = dfncnt++; stk.push(cur); for (auto to : edges[cur]) if (dfn[to.first] == -1) { Tarjan(to.first); low[cur] = min(low[cur], low[to.first]); } elseif (scc[to.first] == -1) low[cur] = min(low[cur], dfn[to.first]); if (low[cur] == dfn[cur]) { int tmp; do { tmp = stk.top(); stk.pop(); scc[tmp] = scccnt; sizescc[scc[tmp]]++; } while (tmp != cur); scccnt++; } }
intmain() { memset(dfn, -1, sizeof(dfn)); memset(low, -1, sizeof(low)); memset(scc, -1, sizeof(scc)); scanf("%d%d%d", &n, &m1, &m2); for (registerint i = 1, u, v; i <= m1; i++) { scanf("%d%d", &u, &v); edges[u].push_back(make_pair(v, 1)); edges[v].push_back(make_pair(u, -1)); } for (registerint i = 1, u, v; i <= m2; i++) { scanf("%d%d", &u, &v); edges[v].push_back(make_pair(u, 0)); }
for (int i = 1; i <= n; i++) if (dfn[i] == -1) Tarjan(i);
int ans = 0, flag = false; for (int i = 0; i < scccnt; i++) { if ((flag = Floyd(i))) break; int dismax = 0; for (registerint j = 1; j <= n; j++) if (scc[j] == i) for (registerint k = 1; k <= n; k++) if (scc[k] == i && dismax < dis[j][k]) dismax = dis[j][k]; ans += dismax + 1; }