【BZOJ】【1051】【HAOI2005】受欢迎的牛

按B->A连边,tarjan缩点,然后找入度为0的连通分量,如果有1个,则ans=size[i],如果大于一个则ans=0;

当然如果按A->B连边就是找出度为0的(表示没有被它喜欢的,这样的连通分量才有可能所被所有的喜欢)

 1 /**************************************************************
 2     Problem: 1051
 3     User: Tunix
 4     Language: C++
 5     Result: Accepted
 6     Time:52 ms
 7     Memory:2308 kb
 8 ****************************************************************/
 9  
10 //BZOJ 1051
11 #include<vector>
12 #include<cstdio>
13 #include<cstring>
14 #include<cstdlib>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 using namespace std;
21 const int N=10086;
22  
23 void read(int &v){
24     v=0;int sign=1; char ch=getchar();
25     while(ch<'0' || ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
26     while(ch>='0'&&ch<='9'){v=v*10+ch-'0'; ch=getchar();}
27     v*=sign;
28 }
29 /****************tamplate***********************/
30 int n,m;
31 int head[N],to[N*5],next[N*5],cnt;
32 void add(int a,int b){
33     to[++cnt]=b; next[cnt]=head[a]; head[a]=cnt;
34 }
35 int dfn[N],low[N],belong[N],du[N],dfs_clock,size[N],SCC;
36 bool inst[N];
37 int st[N],top;
38 void tarjan(int x){
39     int y;
40     dfn[x]=low[x]=++dfs_clock;
41     st[top++]=x;
42     inst[x]=1;
43     for(int i=head[x];i;i=next[i]){
44         y=to[i];
45         if (!dfn[y]){
46             tarjan(y);
47             low[x]=min(low[x],low[y]);
48         }
49         else if (inst[y]) low[x]=min(low[x],dfn[y]);
50     }
51     if (dfn[x]==low[x]){
52         SCC++;size[SCC]=0;
53         for(y=0;y!=x;){
54             y=st[--top];
55             inst[y]=0;
56             belong[y]=SCC;
57             size[SCC]++;
58         }
59     }
60 }
61 void rebuild(){
62     F(x,1,n)
63         for(int i=head[x];i;i=next[i])
64             if (belong[x]!=belong[to[i]]) du[belong[to[i]]]++;
65 }
66 /***********************************************/
67 int main(){
68     read(n); read(m);
69     int a,b;
70     F(i,1,m){
71         read(a); read(b);
72         add(b,a);
73     }
74     F(i,1,n) if (!dfn[i]) tarjan(i);
75     rebuild();
76     int ans=0;
77     if (SCC==1) ans=n;
78     else{
79         int tot=0;
80         F(i,1,SCC) if (du[i]==0) {tot++; ans=size[i];}
81         if (tot>1) ans=0;
82     }
83     printf("%d\n",ans);
84     return 0;
85 }
View Code

 

posted @ 2015-01-18 11:52  Tunix  阅读(169)  评论(0编辑  收藏  举报