poj 2186 有向图强连通分量
奶牛互相之间有爱慕关系,找到被其它奶牛都喜欢的奶牛的数目
用tarjan缩点,然后判断有向图中出度为0的联通分量的个数,如果为1就输出联通分量中的点的数目,否则输出0.
算法源自kb模板
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 const int MAXN=20010;//点数 5 const int MAXM=50010;//边数 6 struct Edge 7 { 8 int to,next; 9 }edge[MAXM]; 10 int head[MAXN],tot; 11 int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc 12 int Index,top; 13 int scc;//强连通分量的个数 14 bool Instack[MAXN]; 15 int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc 16 //num数组不一定需要,结合实际情况 17 int out[MAXN],tmp,Num,ans; 18 void addedge(int u,int v) 19 { 20 edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++; 21 } 22 void Tarjan(int u) 23 { 24 int v; 25 Low[u]=DFN[u]=++Index; 26 Stack[top++]=u; 27 Instack[u]=true; 28 for(int i=head[u];i != -1;i=edge[i].next) 29 { 30 v=edge[i].to; 31 if(!DFN[v]) 32 { 33 Tarjan(v); 34 if(Low[u] > Low[v])Low[u]=Low[v]; 35 } 36 else if(Instack[v] && Low[u] > DFN[v]) 37 Low[u]=DFN[v]; 38 } 39 if(Low[u]==DFN[u]) 40 { 41 scc++; 42 do 43 { 44 v=Stack[--top]; 45 Instack[v]=false; 46 Belong[v]=scc; 47 num[scc]++; 48 } 49 while(v != u); 50 } 51 } 52 void solve(int N) 53 { 54 memset(out,0,sizeof(out)); 55 memset(Belong,0,sizeof(Belong)); 56 memset(DFN,0,sizeof(DFN)); 57 memset(Instack,false,sizeof(Instack)); 58 memset(num,0,sizeof(num)); 59 Index=scc=top=0; 60 for(int i=1;i <= N;i++) 61 if(!DFN[i]) 62 Tarjan(i); 63 } 64 void init() 65 { 66 tot=0; 67 memset(head,-1,sizeof(head)); 68 } 69 int main() 70 { 71 int n,m; 72 int i,j,v; 73 //freopen("1.in","r",stdin); 74 while(scanf("%d%d",&n,&m)!=EOF) 75 { 76 init(); 77 int q,p; 78 for(i=1;i<=m;i++) 79 { 80 scanf("%d%d",&p,&q); 81 addedge(p,q); 82 } 83 solve(n); 84 for(i=1;i<=n;i++) 85 { 86 for(v=head[i];v!=-1;v=edge[v].next) 87 { 88 if(Belong[i]!=Belong[edge[v].to]) 89 { 90 out[Belong[i]]++; 91 } 92 } 93 } 94 ans=0,Num=0; 95 for(i=1;i<=scc;i++) 96 { 97 if(!out[i]) 98 { 99 Num++; 100 tmp = i; 101 } 102 } 103 if(Num==1) 104 { 105 for(i=1;i<=n;i++) 106 { 107 if(Belong[i]==tmp) 108 ans++; 109 } 110 printf("%d\n",ans); 111 } 112 else 113 { 114 printf("0\n"); 115 } 116 } 117 return 0; 118 }