bzoj 1051
Description
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
牛被所有的牛认为是受欢迎的。
Input
第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
能出现多个A,B)
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
3 3
1 2
2 1
2 3
1 2
2 1
2 3
Sample Output
1
思路:强连通,初度为0的联通块就是了
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=10004; 4 const int M=50004; 5 6 struct node{ 7 int from,to,next; 8 }e[M]; 9 int head[N],tot; 10 int dfn[N],low[N],belong[N]; 11 int instack[N]; 12 int Stack[N],index1,top,bcnt; 13 int chu[N],a[N]; 14 15 void add(int u,int v){ 16 e[tot].from=u; 17 e[tot].to=v; 18 e[tot].next=head[u]; 19 head[u]=tot++; 20 } 21 void init(){ 22 memset(dfn,0,sizeof(dfn)); 23 memset(head,-1,sizeof(head)); 24 index1=top=bcnt=0; 25 } 26 void tarjan(int u){ 27 dfn[u]=low[u]=++index1; 28 instack[u]=1; 29 Stack[++top]=u; 30 for(int i=head[u];i!=-1;i=e[i].next){ 31 int v=e[i].to; 32 if(!dfn[v]){ 33 tarjan(v); 34 low[u]=min(low[u],low[v]); 35 } else if(instack[v]){ 36 low[u]=min(low[u],dfn[v]); 37 } 38 } 39 int v; 40 if(dfn[u]==low[u]){ 41 bcnt++; 42 do{ 43 v=Stack[top--]; 44 instack[v]=0; 45 belong[v]=bcnt; 46 a[bcnt]++; 47 } while(u!=v); 48 } 49 } 50 int main(){ 51 int n,m; 52 int x,y; 53 init(); 54 scanf("%d%d",&n,&m); 55 for(int i=1;i<=m;i++){ 56 scanf("%d%d",&x,&y); 57 add(x,y); 58 } 59 for(int i=1;i<=n;i++) 60 if(!dfn[i]) tarjan(i); 61 for(int i=0;i<tot;i++){ 62 if(belong[e[i].from]!=belong[e[i].to]){ 63 chu[belong[e[i].from]]=1; 64 } 65 } 66 67 int sum=0; 68 for(int i=1;i<=bcnt;i++){ 69 if(!chu[i]) 70 sum+=a[i]; 71 } 72 printf("%d\n",sum); 73 }