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

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 }

 

posted on 2017-06-14 22:03  hhhhx  阅读(93)  评论(0编辑  收藏  举报

导航