POJ-2186 Popular Cows

Posted on 2021-12-09 16:24  Capterlliar  阅读(19)  评论(0编辑  收藏  举报

题意:奶牛之间的崇拜具有传递性(刚上完离散数学发出小草的声音.mp3),给出一些崇拜关系,求是否存在奶牛被所有奶牛崇拜。如果存在,输出奶牛的数量。

解:如果奶牛之间形成一个环,它们互相崇拜;如果这个环中的奶牛被其余奶牛崇拜,那么它们被所有奶牛崇拜。所以一个环可视作一个点,如果从所有点均可到达这个点,那么输出这个点的大小。所以先缩点。缩完点判断哪些点能被其余所有点到达。n方肯定是会超时的。现在这张图上没有了环,可以看作一棵或多棵树(多棵肯定不行),这棵树只能有一个叶子结点,也就是没有出度。每个点遍历一遍出边,顺带一提因为只要排除掉它所在环里的点,新图其实不用建立。

代码:

 1 #include <algorithm>
 2 #include <stack>
 3 #include <vector>
 4 #include <stdio.h>
 5 using namespace std;
 6 #define maxx 10005
 7 #define maxn 10005
 8 #define maxm 50005
 9 #define inf 0x3f3f3f3f
10 int n,m;
11 vector<int> e[maxm];
12 int dfn[maxn]={0},low[maxn]={0};
13 int cnt=0,vis[maxn]={0};
14 int colornum=0,color[maxn]={0},num[maxn]={0};
15 stack<int> s;
16 int out[maxn];
17 void paint(int x){
18     s.pop();
19     vis[x]=1;
20     color[x]=colornum;
21     num[colornum]++;
22 }
23 void tarjan(int now){
24     dfn[now]=low[now]=++cnt;
25     s.push(now);
26     vis[now]=1;
27     for(int i=0;i<e[now].size();i++){
28         int to=e[now][i];
29         if(!dfn[to]) {
30             tarjan(to);
31             low[now]=min(low[now],low[to]);
32         }
33         else if(vis[to])
34             low[now]=min(low[now],dfn[to]);
35     }
36     if(low[now]==dfn[now]){
37         colornum++;
38         while(s.top()!=now)
39             paint(s.top());
40         paint(now);
41     }
42 }
43 signed main() {
44     scanf("%d%d",&n,&m);
45     for(int i=0;i<m;i++){
46         int x,y;
47         scanf("%d%d",&x,&y);
48         e[x].push_back(y);
49     }
50     for(int i=1;i<=n;i++) {
51         if (!dfn[i])
52             tarjan(i);
53     }
54     for(int i=1;i<=n;i++){
55         for(int j=0;j<e[i].size();j++){
56             int to=e[i][j];
57             if(color[to]!=color[i])
58                 out[color[i]]++;
59         }
60     }
61     int ans=0;
62     for(int i=1;i<=colornum;i++)
63         if(!out[i]){
64             if(ans==0)
65                 ans=num[i];
66             else ans=-1;
67         }
68     printf("%d\n",ans==-1?0:ans);
69     return 0;
70 }
View Code