classgraph { private: linkedList arr1[maxN]; linkedList arr2[maxN]; linkedList arr[maxN]; int inDeg[maxN]; bool reach1[maxN]; int inv[maxN]; int invCnt; int color[maxN]; int scc[maxN]; int sccCnt; intsize; int ans[maxN]; bool reach2[maxN]; int s; int res[maxN]; int count; public: graph() { size = 0; } graph(int n) { size = n; initialize(); } ~graph() { } voidinitialize(){ sccCnt = 0; s = 0; count = 0; invCnt = 0; for (int i = 0; i <= size; i++) { inDeg[i] = 0; reach1[i] = false; color[i] = 0; scc[i] = 0; ans[i] = 0; res[i] = 0; } } voidadd(int p1, int p2){ arr1[p1].add(p2); } voidinvertedAdd(int p1, int p2){ arr2[p1].add(p2); } voidADD(int p1, int p2){ arr[p1].add(p2); inDeg[p2]++; } voiddfs1(int s){ reach1[s] = true; for (node* p = arr1[s].getHeader(); p != NULL; p = p->next) { int ele = p->ele; if (!reach1[ele]) dfs1(ele); } inv[++invCnt] = s; } voiddfs2(int s, int sccCnt){ color[s] = sccCnt; scc[sccCnt]++; for (node* p = arr2[s].getHeader(); p != NULL; p = p->next) { int ele = p->ele; if (!color[ele]) dfs2(ele, sccCnt); } } voidkosaraju(){ for (int i = 1; i <= size; i++) if (!reach1[i]) dfs1(i);
for (int i = size; i >= 1; i--) { int x = inv[i]; if (!color[x]) { sccCnt++; dfs2(x, sccCnt); } } } voiddfs3(int x){ reach2[x] = true; for (node* p = arr[x].getHeader(); p != NULL; p = p->next) { int ele = p->ele; if (!reach2[ele]) { ans[s] += scc[ele]; dfs3(ele); } } } intsolve(){ kosaraju();
for (int i = 1; i <= size; i++) { for (node* p = arr2[i].getHeader(); p != NULL; p = p->next) { int ele = p->ele; if (color[i] == color[ele]) continue; ADD(color[i], color[ele]); } }
count = 0; for (int i = 1; i <= sccCnt; i++) { if (inDeg[i] == 0) { memset(reach2, false, maxN); ans[i] += (scc[i] - 1); s = i; dfs3(i); count = max(count, ans[i]); } }
return count; } voidsolve2(){ for (int i = 1; i <= sccCnt; i++) if (ans[i] == count) res[i] = 1;
int pos = 0; for (int i = 1; i <= size; i++) { if (res[color[i]]) if (pos == 0) { printf("%d", i - 1); pos++; } else printf(" %d", i - 1); } printf("\n"); } };
intmain(){ int t; scanf_s("%d", &t); for (int ii = 1; ii <= t; ii++) { int n, m; scanf_s("%d%d", &n, &m); graph G(n); for (int i = 0; i < m; i++) { int p1, p2; scanf_s("%d%d", &p1, &p2); G.add(p1 + 1, p2 + 1); G.invertedAdd(p2 + 1, p1 + 1); } int r = G.solve(); printf("Case %d: %d\n", ii, r); G.solve2(); G.~graph(); }