【bzoj1051】 [HAOI2006]受歡迎的牛
阿新 • • 發佈:2017-10-11
pop turn 連通 表示 都是 next ios nod 自己
輸出樣例#1:
題目描述
每頭奶牛都夢想成為牛棚裏的明星。被所有奶牛喜歡的奶牛就是一頭明星奶牛。所有奶
牛都是自戀狂,每頭奶牛總是喜歡自己的。奶牛之間的“喜歡”是可以傳遞的——如果A喜
歡B,B喜歡C,那麽A也喜歡C。牛欄裏共有N 頭奶牛,給定一些奶牛之間的愛慕關系,請你
算出有多少頭奶牛可以當明星。
輸入輸出格式
輸入格式:
? 第一行:兩個用空格分開的整數:N和M
? 第二行到第M + 1行:每行兩個用空格分開的整數:A和B,表示A喜歡B
輸出格式:
? 第一行:單獨一個整數,表示明星奶牛的數量
輸入輸出樣例
輸入樣例#1:3 3 1 2 2 1 2 3
1
說明
只有 3 號奶牛可以做明星
【數據範圍】
10%的數據N<=20, M<=50
30%的數據N<=1000,M<=20000
70%的數據N<=5000,M<=50000
100%的數據N<=10000,M<=50000
題解:
反向建圖(好理解),tarjan強連通分量縮點,入度為0的點若只有一個則輸出其代表強連通分量的大小,否則無解。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5#include<stack> 6 #define maxn 10005 7 #define maxm 50005 8 using namespace std; 9 int read(){ 10 int x=0,f=1;char ch=getchar(); 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 x*f;14 } 15 struct node{int to,next;}e[maxm]; 16 int n,m,cnt,last[maxn],dfn[maxn],low[maxn],idex=0,Bcnt=0,instack[maxn],v[maxn],belong[maxn],rd[maxn],ans=0,tmp; 17 stack<int> stap; 18 void add(int u,int v){e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;} 19 void tarjan(int s){ 20 int t; 21 dfn[s]=low[s]=++idex; 22 stap.push(s); 23 instack[s]=1; 24 for(int i=last[s];i;i=e[i].next){ 25 t=e[i].to; 26 if(!dfn[t]){ 27 tarjan(t); 28 low[s]=min(low[s],low[t]); 29 } 30 else if(instack[t]) low[s]=min(low[s],low[t]); 31 } 32 if(dfn[s]==low[s]){ 33 Bcnt++; 34 do{ 35 t=stap.top(); 36 stap.pop(); 37 instack[t]=false; 38 belong[t]=Bcnt; 39 v[Bcnt]++; 40 }while(s!=t); 41 } 42 } 43 int main(){ 44 n=read(),m=read(); 45 for(int i=1;i<=m;i++){ 46 int u=read(),v=read(); 47 add(v,u); 48 } 49 for(int i=1;i<=n;i++) 50 if(!dfn[i]) 51 tarjan(i); 52 for(int i=1;i<=n;i++) 53 for(int j=last[i];j;j=e[j].next){ 54 int v=e[j].to; 55 if(belong[i]!=belong[v]) 56 rd[belong[v]]++; 57 } 58 for(int i=1;i<=Bcnt;i++) 59 if(rd[i]==0){ 60 ans++; 61 tmp=i; 62 } 63 if(ans==1) printf("%d",v[tmp]); 64 else printf("0"); 65 return 0; 66 }
【bzoj1051】 [HAOI2006]受歡迎的牛