bzoj1051(明星奶牛)

这道就是明星奶牛,A了一次又一次了,(⊙o⊙)…(⊙o⊙)…

去年pas就打了不下5次,就是强联通缩点,然后求出度为0的块

判断有多个的话就无解,一个就输出块的大小。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 
 8 const int NN=1e4+7,MM=NN*5;
 9 
10 int n,m,Time=0,top=0,scc=0,ans;
11 int dfn[NN],low[NN],instack[NN],q[NN],belong[NN],chu[NN];
12 int cnt=0,head[NN],next[MM],rea[MM],skt[NN];
13 
14 void add(int u,int v)
15 {
16     cnt++;
17     next[cnt]=head[u];
18     head[u]=cnt;
19     rea[cnt]=v;
20 }
21 void tarjan(int u)
22 {
23     low[u]=dfn[u]=++Time;
24     q[++top]=u,instack[u]=1;
25     for (int i=head[u];i!=-1;i=next[i])
26     {
27         int v=rea[i];
28         if (dfn[v]==0)
29         {
30             tarjan(v);
31             low[u]=min(low[v],low[u]);
32         }
33         else if (instack[v]) low[u]=min(low[u],dfn[v]);
34     }
35     if (low[u]==dfn[u])
36     {
37         scc++;
38         int x=-1;
39         while (x!=u)
40         {
41             x=q[top--];
42             instack[x]=0;
43             belong[x]=scc;
44             ++skt[scc];
45         }
46     }
47 }
48 void rebuild()
49 {
50     for (int u=1;u<=n;u++)
51     {
52         for (int i=head[u];i!=-1;i=next[i])
53         {
54             int v=rea[i];
55             if (belong[u]!=belong[v]) chu[belong[u]]=1;
56         }
57     }
58     int num=0,x=0;
59     for (int i=1;i<=scc;i++)
60         if (chu[i]==0) num++,x=i;    
61     if (num!=1) ans=0;
62     else ans=skt[x];
63     printf("%d",ans);
64 }
65 int main()
66 {
67     scanf("%d%d",&n,&m);
68     int x,y;
69     memset(head,-1,sizeof(head));
70     for (int i=1;i<=m;i++)
71     {
72         scanf("%d%d",&x,&y);
73         add(x,y);
74     }
75     for (int i=1;i<=n;i++)
76         if (dfn[i]==0) tarjan(i);
77     rebuild();    
78 }

 

posted @ 2017-08-25 21:14  Kaiser-  阅读(...)  评论(... 编辑 收藏