直接tarjan求scc,然后统计出度为0的缩点,如果多余1个就输出0,只有一个就输出这个缩点里的点。
——代码
1 #include <cstdio> 2 #include <cstring> 3 #include <stack> 4 5 using namespace std; 6 7 int n, m, cnt, idx, ans, k; 8 int next[100001], to[100001], head[10001], low[10001], dfn[10001], belong[10001], c[10001]; 9 bool ins[10001]; 10 stack <int> s; 11 12 inline void add(int x, int y) 13 { 14 to[cnt] = y; 15 next[cnt] = head[x]; 16 head[x] = cnt++; 17 } 18 19 inline void tarjan(int u) 20 { 21 low[u] = dfn[u] = ++idx; 22 s.push(u); 23 ins[u] = 1; 24 int i, v; 25 for(i = head[u]; i != -1; i = next[i]) 26 { 27 v = to[i]; 28 if(!dfn[v]) 29 { 30 tarjan(v); 31 low[u] = min(low[u], low[v]); 32 } 33 else if(ins[v]) low[u] = min(low[u], dfn[v]); 34 } 35 if(low[u] == dfn[u]) 36 { 37 cnt++; 38 do 39 { 40 v = s.top(); 41 s.pop(); 42 ins[v] = 0; 43 belong[v] = cnt; 44 }while(u != v); 45 } 46 } 47 48 int main() 49 { 50 int i, j, x, y, u, v; 51 memset(head, -1, sizeof(head)); 52 scanf("%d %d", &n, &m); 53 for(i = 1; i <= m; i++) 54 { 55 scanf("%d %d", &x, &y); 56 add(x, y); 57 } 58 cnt = 0; 59 for(i = 1; i <= n; i++) 60 if(!dfn[i]) 61 tarjan(i); 62 for(u = 1; u <= n; u++) 63 for(i = head[u]; i != -1; i = next[i]) 64 { 65 v = to[i]; 66 if(belong[u] != belong[v]) c[belong[u]]++; 67 } 68 for(i = 1; i <= cnt; i++) 69 if(!c[i]) 70 { 71 ans++; 72 k = i; 73 } 74 if(ans > 1) printf("0"); 75 else 76 { 77 ans = 0; 78 for(i = 1; i <= n; i++) 79 if(belong[i] == k) 80 ans++; 81 printf("%d", ans); 82 } 83 return 0; 84 }