【POJ2186 最受欢迎的牛】

时间:2021-10-11 20:46:47

题目大意:

      每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这

种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头

牛被所有的牛认为是受欢迎的。


题解

  先tarjan缩点,对于新建的图中,出度为0的点如果只有一个,说明这个点(缩过)被所有奶牛欢迎。否则的话就不可能有

奶牛被所有的牛认为是受欢迎。

 1 #include<iostream>
2 #include<cstdlib>
3 #include<cstring>
4 #include<cstdio>
5 #include<algorithm>
6 struct nd1
7 {
8 int next,to;
9 } e1[150005];
10 int head[110005],out[110005],sc,cnt;
11 inline void insert(int u,int v)
12 {
13 e1[++cnt].next=head[u];
14 head[u]=cnt;
15 e1[cnt].to=v;
16 }
17 int time,s[110005],vis[110005],dfn[110005],low[110005],bl[110005],num[110005];
18 int n,m;
19 inline void tarjan(int now)
20 {
21 dfn[now]=low[now]=++time;
22 s[++s[0]]=now;vis[now]=1;
23 for(int i=head[now];i;i=e1[i].next)
24 {
25 if(!dfn[e1[i].to])
26 {
27 tarjan(e1[i].to);
28 low[now]=std::min(low[now],low[e1[i].to]);
29 }
30 else if(vis[e1[i].to])
31 low[now]=std::min(low[now],dfn[e1[i].to]);
32 }
33 if(dfn[now]==low[now])
34 {
35 num[bl[now]=++sc]=1;
36 vis[now]=0;
37 while(s[s[0]]!=now)
38 {
39 vis[s[s[0]]]=0;
40 bl[s[s[0]]]=sc;
41 num[sc]++;
42 s[0]--;
43 }
44 s[0]--;
45 }
46 }
47 inline void rdeg()
48 {
49 for(int i=1;i<=n;i++)
50 for(int j=head[i];j;j=e1[j].next)
51 {
52 if(bl[i]!=bl[e1[j].to])
53 out[bl[i]]++;
54 }
55 }
56 int main()
57 {
58 int u,v;
59 scanf("%d%d",&n,&m);
60 for(int i=1;i<=m;i++)
61 {
62 scanf("%d%d",&u,&v);
63 insert(u,v);
64 }
65 for(int i=1;i<=n;i++)
66 if(!dfn[i]) tarjan(i);
67 rdeg();
68 int ans=0;
69 for(int i=1;i<=sc;i++)
70 {
71 if(!out[i] && !ans) ans=num[i];
72 else if(!out[i] && ans!=0)
73 {
74 ans=-1;
75 break;
76 }
77 }
78 if(ans==-1) puts("0\n");
79 else printf("%d\n",ans);
80 return 0;
81 }