先求出强连通,再缩点。然后求一下出度为0的个数,如果出度为0的点只有一个,那个点所对应的集合个数就是答案,否则答案就是0。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 10005 #define maxm 50005 #define eps 1e-10 #define mod 1000000009 #define INF 99999999 #define lowbit(x) (x&(-x)) //#define lson o<<1, L, mid //#define rson o<<1 | 1, mid+1, R typedef long long LL; //typedef int LL; using namespace std; int H[maxn], NEXT[maxm], V[maxm]; int h[maxn], next[maxm], v[maxm]; int dfn[maxn], low[maxn], id[maxn]; int ins[maxn], w[maxn], out[maxn]; stack<int> s; int scc_cnt, top, n, m; void init(void) { top = scc_cnt = 0; memset(h, -1, sizeof h); memset(H, -1, sizeof H); memset(w, 0, sizeof w); memset(ins, 0, sizeof ins); memset(dfn, 0, sizeof dfn); memset(out, 0, sizeof out); } void scanf(int &x) { x = 0; char ch = getchar(); while(ch == ' ' || ch == '\n') ch = getchar(); while(ch >= '0' && ch <= '9') x=x*10+ch-'0', ch = getchar(); } void read(void) { int a, b, cnt = 0; while(m--) { //scanf("%d%d", &a, &b); scanf(a), scanf(b); NEXT[cnt] = H[a], H[a] = cnt, V[cnt] = b, cnt++; } } void tarjan(int u) { dfn[u] = low[u] = ++top; s.push(u), ins[u] = 1; for(int e = H[u]; ~e; e = NEXT[e]) if(!dfn[V[e]]) { tarjan(V[e]); low[u] = min(low[u], low[V[e]]); } else if(ins[V[e]]) low[u] = min(low[u], dfn[V[e]]); if(dfn[u] == low[u]) { int tmp = s.top(); s.pop(), ins[tmp] = 0; ++scc_cnt; while(tmp != u) { id[tmp] = scc_cnt; tmp = s.top(); s.pop(); ins[tmp] = 0; } id[tmp] = scc_cnt; } } void narrow(void) { int cnt = 0; for(int i = 1; i <= n; i++) for(int e = H[i]; ~e; e = NEXT[e]) next[cnt] = h[id[i]], h[id[i]] = cnt, v[cnt] = id[V[e]], cnt++; } void work(void) { int i, k = 0, ans = 0; for(i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); narrow(); for(i = 1; i <= n; i++) w[id[i]]++; for(i = 1; i <= scc_cnt; i++) for(int e = h[i]; ~e; e = next[e]) if(v[e] != i) out[i]++; for(i = 1; i <= scc_cnt; i++) if(!out[i]) k++, ans = i; if(k == 1) printf("%d\n", w[ans]); else printf("0\n"); } int main(void) { while(scanf("%d%d", &n, &m)!=EOF) { init(); read(); work(); } return 0; }