POJ 2186 Popular Cows

Popular Cows

题意:一共有n头牛,m条崇拜关系,并且崇拜关系是可以传递的,偶像的偶像也是自己的偶像,求被除自己以外被其他所有牛崇拜的牛的数量。

题解:将强连通图缩成点,找到出度为0的点,如果有2个及以上就不能达成条件,如果只有一个,那么代表着其他点都有出去的边,且因为强连通锁点了,所以定不存在环,肯定至少有一条边指到出度为0的点

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 const int N = 1e4+5;
 7 struct Node
 8 {
 9     int nt;
10     int to;
11 }E[N*5];
12 int head[N], vis[N], in[N], Stack[N*5], rt[N], low[N], dfn[N], du[N];
13 int tot = 0, n, m, cnt = 0, top = 0, rtcnt = 0;
14 void Add_edge(int u, int v)
15 {
16     E[tot].to = v;
17     E[tot].nt = head[u];
18     head[u] = tot++;
19 }
20 void Tarjan(int u)
21 {
22     vis[u] = in[u] = 1;
23     low[u] = dfn[u] = ++cnt;
24     Stack[++top] = u;
25     for(int i = head[u]; ~i; i = E[i].nt)
26     {
27         int v = E[i].to;
28         if(!vis[v])
29             Tarjan(v);
30         if(in[v])
31             low[u] = min(low[v],low[u]);//这里是更新点u,因为先被访问的点肯定low值小,所以反过来是肯定更新不了的
32     }
33     if(low[u] == dfn[u])
34     {
35         int v;
36         do
37         {
38             v = Stack[top--];
39             in[v] = 0;
40             rt[v] = rtcnt;
41         }while(v != u);
42         rtcnt++;
43     }
44 }
45 int main()
46 {
47     memset(head, -1, sizeof(head));
48     memset(du, 0, sizeof(du));
49     memset(vis, 0, sizeof(vis));
50     scanf("%d%d",&n,&m);
51     int u, v;
52     for(int i = 0; i < m; i++)
53     {
54         scanf("%d%d",&u,&v);
55         Add_edge(u,v);
56     }
57     for(int i = 1; i <= n; i++)
58       if(!vis[i])  Tarjan(i);
59     for(int i = 1; i <= n; i++)
60     {
61         for(int j = head[i]; ~j; j = E[j].nt)
62         {
63             int v = E[j].to;
64             if(rt[v] != rt[i])
65                 du[rt[i]]++;
66         }
67     }
68     int cnt_in = 0, ans_rt;
69     for(int i = 0; i < rtcnt; i++ )
70     {
71         if(du[i] == 0) cnt_in++, ans_rt = i;
72     }
73     if(cnt_in == 1)
74     {
75         int ans = 0;
76         for(int i = 1; i <= n; i++)
77         {
78             if(ans_rt == rt[i]) ans++;
79         }
80         printf("%d
",ans);
81     }
82     else printf("0
");
83 
84     return 0;
85 }
原文地址:https://www.cnblogs.com/MingSD/p/8444164.html