题解:[HAOI2006]受欢迎的牛

qwq

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<stack>
 6 using namespace std;
 7 const int maxn=1e6;
 8 int head[maxn], cnt;
 9 int dfn[maxn], low[maxn];
10 int st[maxn], top, belong[maxn], sz[maxn];
11 bool in[maxn];
12 int n, m, chu[maxn];
13 int num, scc;
14 stack<int> q;
15 struct cow{
16     int to, next;
17 }a[maxn<<1];
18 void add(int from, int to){
19     cnt++;
20     a[cnt].to=to;
21     a[cnt].next=head[from];
22     head[from]=cnt;
23 }
24 void tarjan(int u){//缩点 
25     dfn[u]=low[u]=++num;
26     in[u]=true;
27     q.push(u);
28     for(int i=head[u]; i; i=a[i].next){
29         int v=a[i].to;
30         if(!dfn[v]){
31             tarjan(v);
32             low[u]=min(low[u],low[v]);
33         }
34         else if(in[v]){
35             low[u]=min(low[u],dfn[v]);
36         }
37     }
38     if(dfn[u]==low[u]){
39         int v;
40         scc++;
41         do{
42             v=q.top();
43             q.pop();
44             in[v]=false;
45             sz[scc]++;//scc的大小
46             belong[v]=scc;//每个点属于哪个scc 
47         }while(u!=v);
48     }
49 }
50 int main(){
51     scanf("%d%d",&n,&m);
52     for(int i=1; i<=m; i++){
53         int a, b;
54         scanf("%d%d",&a,&b);
55         add(a, b);
56     }
57     for(int i=1; i<=n; i++){
58         if(!dfn[i]) tarjan(i);
59     }
60     for(int i=1; i<=n; i++){
61             for(int j=head[i]; j; j=a[j].next){
62                 int u=a[j].to;
63                 if(belong[i]!=belong[u]){
64                     chu[belong[i]]++;//记录出度 
65                 }
66             }
67         }
68     int flag=0;
69     for(int i=1; i<=scc; i++){//如果同时有两个scc出度都为0 
70         if(!chu[i]){// 则无法都喜欢,直接输出0 
71             if(flag){
72                 puts("0");
73                 return 0;
74             }
75             else flag=i;//记录第几个scc 
76         }
77     }
78     cout<<sz[flag]<<endl;
79     return 0;
80 }
原文地址:https://www.cnblogs.com/Aze-qwq/p/9910887.html