POJ2186 最受欢迎的牛

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2186 最受欢迎的牛相关的知识,希望对你有一定的参考价值。

题目大意:

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

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

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

输入格式:

  第一行输入n,m

  下面m行每行输入x,y表示x到y有一条边

输出格式:

  输出受欢迎奶牛的数量

输入样例

  3 3
  1 2
  2 1
  2 3

输出样例

  1

题解

  先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 }

 

以上是关于POJ2186 最受欢迎的牛的主要内容,如果未能解决你的问题,请参考以下文章

poj2186--tarjan+缩点

POJ 2186 Popular Cows(强联通分量)

tarjan算法+缩点:求强连通分量 POJ 2186

POJ 2186 Popular Cows

poj 2186 强连通入门题目

不裸缩点》。。。POJ2186受欢迎的牛