【洛谷P2341】受欢迎的牛

受欢迎的牛

题目描述

一些可以当明星的牛,一定会构成一个强连通分量,我们可以先缩点,最后统计一下出度为零的强连通分量大小即可,

若出度为零的强连通分量个数大于1,则输出0

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 10010 
 6 #define M 100010
 7 int n,m,dfn[N],low[N],belong[N],du[N],cnt;
 8 int stack[N],top,size[N],k,head[N],num,tot;
 9 bool instack[N];
10 struct NODE{
11     int to,next;
12 } e[M];
13 inline int read(){
14     int x=0,f=1; char c=getchar();
15     while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); }
16     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
17     return x*f; 
18 }
19 inline void add(int x,int y)
20 {
21     e[++num].to=y;
22     e[num].next=head[x];
23     head[x]=num;
24 }
25 void Tarjan(int u){
26     dfn[u]=low[u]=++cnt;
27     stack[++top]=u;
28     instack[u]=1;
29     for(int i=head[u];i;i=e[i].next)
30      if(!dfn[e[i].to]){
31         Tarjan(e[i].to);
32         low[u]=min(low[u],low[e[i].to]);
33      }
34      else if(instack[e[i].to])
35       low[u]=min(low[u],dfn[e[i].to]);
36     if(low[u]==dfn[u]){
37         belong[u]=++tot;
38         size[tot]++;    //记录强连通分量大小
39         while(stack[top]!=u){
40             int t=stack[top];
41             belong[t]=tot;
42             instack[t]=0;
43             size[tot]++;
44             top--;
45         }
46         top--;
47         instack[u]=0;
48     }
49 }
50 int main()
51 {
52     scanf("%d%d",&n,&m);
53     int x,y;
54     for(int i=1;i<=m;i++){
55         x=read(); y=read();
56         add(x,y);
57     }
58     for(int i=1;i<=n;i++)
59      if(!dfn[i])
60       Tarjan(i);
61     for(int i=1;i<=n;i++)
62      for(int j=head[i];j;j=e[j].next)  //统计出度
63       if(belong[i]!=belong[e[j].to])
64        du[belong[i]]++;
65     int ans=0;
66     for(int i=1;i<=tot;i++)
67      if(!du[i]){
68          ans=size[i];
69          k++;
70      }
71     if(k==1)
72      printf("%d\n",ans);
73     else puts("0");
74     return 0;
75 }

 

posted @ 2018-07-04 08:33  yjk  阅读(150)  评论(0编辑  收藏  举报