题目中文翻译:
Description
每头牛的梦想就是成为牛群中最受欢迎的牛。 在一群N(1 <= N <= 10,000)母牛中,你可以得到M(1 <= M <= 50,000)有序的形式对(A,B),告诉你母牛A认为母牛 B很受欢迎。 由于流行是传递性的,如果A认为B很受欢迎,B认为C受欢迎,那么A也会认为C是受欢迎的,即使这不是输入中有序对明确规定的。 你的任务是计算被其他所有奶牛欢迎的奶牛总数量。
Input
*第1行:两个空格分隔的整数,N和M.
*第2..1 + M行:两个空格分隔的数字A和B,表示A认为B很受欢迎。
Output
*第1行:单个整数,即被其他所有奶牛欢迎的奶牛总数量。
Sample Input
3 3
1 2
2 1
2 3
Sample Output
1
Hint
Cow 3 is the only cow of high popularity.
首先tarjan求强连通分量,缩点找没有出度的点,如果只有一个,则答案为这个点代表的强连通分量里面所有点,如果大于一个,则答案为0.
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<stack> 5 6 using namespace std; 7 8 int n,m,tot,head[10001],dfn[10001],num[10001],sum,low[10001],csp,belong[10001],outd[10001]; 9 bool _in[10001]; 10 struct kkk { 11 int to,next,from; 12 bool pp; 13 }e[50003]; 14 stack<int> a; 15 16 inline void add(int x,int y) { 17 e[++tot].to = y; 18 e[tot].next = head[x]; 19 e[tot].from = x; 20 head[x] = tot; 21 } 22 23 inline void tarjan(int x) { 24 int v; 25 dfn[x] = low[x] = ++sum; 26 a.push(x); 27 _in[x] = 1; 28 for(int i = head[x];i != -1; i = e[i].next) { 29 v = e[i].to; 30 if(!dfn[v]) { 31 tarjan(v); 32 low[x] = min(low[x],low[v]); 33 } 34 else if(_in[v]) 35 low[x] = min(low[x],dfn[v]); 36 } 37 if(dfn[x] == low[x]) { 38 csp++; 39 do { 40 v = a.top(); 41 a.pop(); 42 _in[v] = false; 43 num[csp]++; 44 belong[v] = csp; 45 } 46 while(v != x); 47 } 48 } 49 50 int main() 51 { 52 memset(head,-1,sizeof(head)); 53 scanf("%d%d",&n,&m); 54 for(int i = 1;i <= m; i++) { 55 int x,y; 56 scanf("%d%d",&x,&y); 57 add(x,y); 58 e[i].pp = 0; 59 } 60 for(int i = 1;i <= n; i++) 61 if(!dfn[i]) 62 tarjan(i); 63 for(int i = 1;i <= n; i++) 64 for(int j = head[i];j != -1; j = e[j].next) { 65 if(belong[e[j].to] != belong[i]) 66 outd[belong[i]]++; 67 } 68 int ans = -1; 69 for(int i = 1;i <= csp; i++) { 70 if(outd[i] == 0) 71 if(ans == -1) 72 ans = num[i]; 73 else{ 74 printf("0"); 75 return 0; 76 } 77 } 78 printf("%d",ans); 79 return 0; 80 }
原文:https://www.cnblogs.com/lipeiyi520/p/11440059.html