题意:有 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);
77 else{
78 for(int i=1;i<=scccnt;++i)if(!od[i])ans++;
79 if(ans!=1){
80 printf("0
");
81 }
82 else{
83 ans=0;
84 for(int i=1;i<=n;++i){
85 if(!od[scc[i]])ans++;
86 }
87 printf("%d
",ans);
88 }
89 }
90 }
91 return 0;
92 }