这道题实质就是缩点,缩完点后一定是$DAG$,统计每个缩点的大小。如果有且只有一个缩点的出度为$0$,说明其他所有点都会直接或间接到达这个点。
1 #include2 3 using namespace std; 4 5 #define re register 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 7 #define repd(i, a, b) for (re int i = a; i >= b; --i) 8 #define maxx(a, b) a = max(a, b); 9 #define minn(a, b) a = min(a, b);10 #define LL long long11 #define inf (1 << 30)12 13 inline int read() {14 int w = 0, f = 1; char c = getchar();15 while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();16 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();17 return w * f;18 }19 20 const int maxn = 1e4 + 5, maxm = 5e4 + 5;21 22 struct Edge {23 int u, v, pre;24 };25 26 struct Graph {27 Edge edges[maxm << 1];28 int n, m;29 int G[maxn];30 int dfs_clock, sccno[maxn], scc_cnt, cnt[maxn], pre[maxn], low[maxn];31 void init(int n) {32 this->n = n;33 m = 0;34 memset(G, 0, sizeof(G));35 dfs_clock = scc_cnt = 0;36 }37 void Add(int u, int v) {38 edges[++m] = (Edge){u, v, G[u]};39 G[u] = m;40 }41 stack s;42 void dfs(int u) {43 pre[u] = low[u] = ++dfs_clock;44 s.push(u);45 for (int i = G[u]; i; i = edges[i].pre) {46 register int v = edges[i].v;47 if (!pre[v]) {48 dfs(v); minn(low[u], low[v]);49 }50 else if (!sccno[v]) minn(low[u], pre[v]);51 }52 if (pre[u] == low[u]) {53 int x = 0; scc_cnt++;54 while (x != u) {55 x = s.top(); s.pop();56 sccno[x] = scc_cnt;57 cnt[scc_cnt]++;58 }59 }60 }61 } G;62 63 int n, m, b[maxn];64 65 int main() {66 n = read(), m = read();67 G.init(n);68 69 rep(i, 1, m) {70 int u = read(), v = read();71 G.Add(u, v);72 }73 rep(i, 1, n) if (!G.sccno[i]) G.dfs(i);74 75 rep(i, 1, G.m) {76 int u = G.edges[i].u, v = G.edges[i].v;77 if (G.sccno[u] != G.sccno[v])78 b[G.sccno[u]] = 1;79 }80 81 int ans = 0;82 rep(i, 1, G.scc_cnt) 83 if (!b[i]) {84 if (ans) { ans = 0; break; }85 ans = i;86 }87 88 printf("%d", G.cnt[ans]);89 90 return 0;91 }