题意:有 n 头牛,以及一些喜欢关系,牛 A 喜欢牛 B,这种关系可以传递,问有多少头牛被牧场上所有牛喜欢。

首先强连通,因为在同一个强连通分量中牛是等价的,然后对于一个有向无环图看是否只有一个强连通分量出度为 0 ,如果是,则这个强连通分量中的点都是答案,否则为 0。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stack>
 4 #include<queue>
 5 using namespace std;
 6 
 7 const int maxn=10005;
 8 const int maxm=50005;
 9 
10 int head[maxn],point[maxm],nxt[maxm],size;
11 int n,t,scccnt;
12 int stx[maxn],low[maxn],scc[maxn],od[maxn];
13 stack<int>S;
14 
15 void init(){
16     memset(head,-1,sizeof(head));
17     size=0;
18     memset(od,0,sizeof(od));
19 }
20 
21 void add(int a,int b){
22     point[size]=b;
23     nxt[size]=head[a];
24     head[a]=size++;
25 }
26 
27 void dfs(int s){
28     stx[s]=low[s]=++t;
29     S.push(s);
30     for(int i=head[s];~i;i=nxt[i]){
31         int j=point[i];
32         if(!stx[j]){
33             dfs(j);
34             low[s]=min(low[s],low[j]);
35         }
36         else if(!scc[j]){
37             low[s]=min(low[s],stx[j]);
38         }
39     }
40     if(low[s]==stx[s]){
41         scccnt++;
42         while(1){
43             int u=S.top();S.pop();
44             scc[u]=scccnt;
45             if(s==u)break;
46         }
47     }
48 }
49 
50 void setscc(){
51     memset(stx,0,sizeof(stx));
52     memset(scc,0,sizeof(scc));
53     t=scccnt=0;
54     for(int i=1;i<=n;++i)if(!stx[i])dfs(i);
55     for(int i=1;i<=n;++i){
56         for(int j=head[i];~j;j=nxt[j]){
57             int k=point[j];
58             if(scc[i]!=scc[k]){
59                 od[scc[i]]++;
60             }
61         }
62     }
63 }
64 
65 int main(){
66     int m;
67     while(scanf("%d%d",&n,&m)!=EOF){
68     init();
69     while(m--){
70         int a,b;
71         scanf("%d%d",&a,&b);
72         add(a,b);
73     }
74     setscc();
75     int ans=0;
76     if(scccnt==1)printf("%d\n",n);
77     else{
78         for(int i=1;i<=scccnt;++i)if(!od[i])ans++;
79         if(ans!=1){
80             printf("0\n");
81         }
82         else{
83             ans=0;
84             for(int i=1;i<=n;++i){
85                 if(!od[scc[i]])ans++;
86             }
87             printf("%d\n",ans);
88         }
89     }
90     }
91     return 0;
92 }
View Code