题解:[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 }
"Hello World!"