rt,如果缩点之后的图的入度是强联通分量的数量 - 1的话应该也是可以的吧?但是这样写之后 WA 44pts ,求大佬解惑qwq
代码:
// P2341 [USACO03FALL / HAOI2006] 受欢迎的牛 G
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10, M = 5e4 + 10;
int n, m;
class Graph {
private:
vector<int> G[N];
public:
int inDegree[N];
void addEdge(int u, int v) {
this->G[u].push_back(v);
this->inDegree[v]++;
}
vector<int> operator[] (int idx) {
return this->G[idx];
}
} G1, G2;
int low[N], dfn[N], color[N], idx = 0, sccCnt = 0;
stack<int> s;
set<int> scc[N];
void tarjan(int u, Graph& G) {
low[u] = dfn[u] = ++idx;
s.push(u);
for (auto v : G[u]) {
if (!dfn[v]) {
tarjan(v, G);
low[u] = min(low[u], low[v]);
} else if (!color[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u]) {
sccCnt++;
while (!s.empty()) {
int x = s.top();
s.pop();
color[x] = sccCnt;
scc[sccCnt].insert(x);
if (x == u) break;
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
G1.addEdge(u, v);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i]) tarjan(i, G1);
}
for (int u = 1; u <= n; u++) {
for (auto v : G1[u]) {
if (color[u] != color[v]) {
G2.addEdge(color[u], color[v]);
}
}
}
long long ans = 0;
for (int i = 1; i <= sccCnt; i++) {
if (G2.inDegree[i] == sccCnt - 1) ans += scc[i].size();
}
printf("%d\n", ans);
return 0;
}