1. 程式人生 > >【tarjan縮點】受歡迎的牛

【tarjan縮點】受歡迎的牛

P2341 [HAOI2006]受歡迎的牛 

縮點令我快樂哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

一遍過編譯一遍A哈哈哈哈哈哈開心快樂哈哈哈哈哈哈哈哈哈哈

好吧其實很簡單

因為牛的愛慕具有傳遞性(愛牛及牛??

所以出度為0的強連通分量內牛的個數即為答案, 但如果存在兩個及兩個以上的出度為0的強連通分量, ans = 0, 因為這些強連通之間不連通qaq

差不多就是這樣啦

noip2018 加油ヾ(◍°∇°◍)ノ゙

 1 #include<cstdio>
 2 #include<iostream>
 3 #define ri register int
 4
#define ll long long 5 #define maxn 10010 6 #define maxm 50050 7 using namespace std; 8 int n, m, num = 0, top = 0, tim = 0, cnt = 0, num2 = 0; 9 int node[maxn], head[maxm], head2[maxm],sd[maxn], chu[maxn], sta[maxn], low[maxn], dfn[maxn], x[maxm], y[maxm]; 10 bool vis[maxn]; 11 struct Edge { 12 int
nxt, to; 13 }e[maxn << 1], edge[maxm << 1]; 14 int read() { 15 char ch = getchar(); int x = 0, f = 1; 16 while(ch > '9' || ch < '0') {if(ch == '-') f = -1; ch = getchar();} 17 while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0' ; ch = getchar();} 18 return
x * f; 19 } 20 void add(int from, int to) { 21 e[++num].nxt = head[from]; 22 e[num].to = to; 23 head[from] = num; 24 } 25 void readd(int from, int to) { 26 chu[from]++; 27 edge[++num2].nxt = head2[from]; 28 edge[num2].to = to; 29 head2[from] = num2; 30 } 31 void tarjan(int x) { 32 low[x] = dfn[x] = ++tim; 33 sta[++top] = x; 34 vis[x] = 1; 35 for(int i = head[x]; i; i = e[i].nxt) { 36 int v = e[i].to; 37 if(!dfn[v]) { 38 tarjan(v); 39 low[x] = min(low[x], low[v]); 40 } 41 else if(vis[v]) low[x] = min(low[x], dfn[v]); 42 } 43 if(dfn[x] == low[x]) { 44 cnt++; 45 while(x != sta[top+1]) { 46 sd[sta[top]] = cnt; 47 vis[sta[top]] = 0; 48 node[cnt]++; 49 top--; 50 } 51 } 52 } 53 void search() { 54 int flag = 0, ans = 0; 55 for(int i = 1; i <= cnt; i++) { 56 if(!chu[i]) { 57 if(!flag) { 58 ans = node[i]; 59 flag = 1; 60 } 61 else { 62 flag = 2; 63 break; 64 } 65 } 66 } 67 if(flag == 1) { 68 printf("%d", ans); 69 return; 70 } 71 else { 72 printf("0"); 73 return; 74 } 75 } 76 int main() { 77 scanf("%d%d", &n, &m); 78 for(ri i = 1; i <= m; i++) { 79 x[i] = read(), y[i] = read(); 80 add(x[i], y[i]); 81 } 82 for(ri i = 1; i <= n; i++) 83 if(!dfn[i]) tarjan(i); 84 for(ri i = 1; i <= m; i++) { 85 int u = sd[x[i]], v = sd[y[i]]; 86 if(u != v) readd(u, v); 87 } 88 search(); 89 return 0; 90 }