bzoj1051: [HAOI2006]受欢迎的牛(强联通)

1051: [HAOI2006]受欢迎的牛

题目:传送门

 

题解:

   今天又做一道水题...

   强联通啊很明显

   水个模板之后统计一下每个强联通分量中点的个数,再统计一下出度...

   不难发现:缩点之后当且仅当仅有一个强联通分量的出度为0,那么这个强连通分量才可以被所有的点访问..

   具体的就自己画下图YY吧...

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define qread(x) x=read()
 7 using namespace std;
 8 inline int read()
 9 {
10     int f=1,x=0;char ch;
11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return f*x; 
14 }
15 struct node
16 {
17     int x,y,next;
18 }a[51000];int len,last[11000];
19 void ins(int x,int y)
20 {
21     len++;
22     a[len].x=x;a[len].y=y;
23     a[len].next=last[x];last[x]=len;
24 }
25 int n,m,id,tp,cnt;
26 int belong[11000],dfn[11000],low[11000],sta[11000];
27 bool v[11000];
28 void dfs(int x)
29 {
30     low[x]=dfn[x]=++id;
31     sta[++tp]=x;v[x]=true;
32     for(int k=last[x];k;k=a[k].next)
33     {
34         int y=a[k].y;
35         if(dfn[y]==-1)
36         {
37             dfs(y);
38             low[x]=min(low[x],low[y]);
39         }
40         else
41         {
42             if(v[y]==true)
43                 low[x]=min(low[x],dfn[y]);
44         }
45     }
46     if(low[x]==dfn[x])
47     {
48         int i;cnt++;
49         do{
50             i=sta[tp--];
51             v[i]=false;
52             belong[i]=cnt;
53         }while(i!=x);
54     }
55 }
56 int num[11000],chu[11000];
57 int main()
58 {
59     qread(n);qread(m);
60     for(int i=1;i<=m;i++)
61     {
62         int x,y;
63         qread(x);qread(y);
64         ins(x,y);
65     }
66     id=tp=cnt=0;
67     memset(dfn,-1,sizeof(dfn));
68     memset(low,0,sizeof(low));
69     memset(belong,0,sizeof(belong));
70     memset(v,false,sizeof(v));
71     for(int i=1;i<=n;i++)
72         if(dfn[i]==-1)
73             dfs(i);
74     if(cnt==1){printf("%d\n",n);return 0;}
75     memset(num,0,sizeof(num));
76     memset(chu,0,sizeof(chu));
77     for(int i=1;i<=n;i++)num[belong[i]]++;
78     for(int i=1;i<=len;i++)
79         if(belong[a[i].x]!=belong[a[i].y])
80             chu[belong[a[i].x]]++;
81     int s=0,k;
82     for(int i=1;i<=cnt;i++)if(chu[i]==0){s++;k=i;}
83     if(s==1)printf("%d\n",num[k]);
84     else printf("0\n");
85     return 0;
86 }

又水一发...

posted @ 2017-12-28 21:16  CHerish_OI  阅读(154)  评论(0编辑  收藏  举报