简单tarjan》一道裸题(BZOJ1051)(easy)
生活随笔
收集整理的這篇文章主要介紹了
简单tarjan》一道裸题(BZOJ1051)(easy)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這是一道水題,實際考察的是你會不會寫強連通分量。。。(在BZOJ上又水了一道題)
?
Description
每一頭牛的愿望就是變成一頭最受歡迎的牛。現在有N頭牛,給你M對整數(A,B),表示牛A認為牛B受歡迎。 這 種關系是具有傳遞性的,如果A認為B受歡迎,B認為C受歡迎,那么牛A也認為牛C受歡迎。你的任務是求出有多少頭 牛被所有的牛認為是受歡迎的。Input
第一行兩個數N,M。 接下來M行,每行兩個數A,B,意思是A認為B是受歡迎的(給出的信息有可能重復,即有可 能出現多個A,B)Output
一個數,即有多少頭牛被所有的牛認為是受歡迎的。
Sample Input
3 31 2
2 1
2 3
Sample Output
1HINT
100%的數據N<=10000,M<=50000 思路:直接強連通分量縮點,然后,因為題目沒有告訴你 ?當沒有一頭牛受歡迎時 ?應該輸出什么,所以我們認為題目一定有解,所以直接tarjan就好啦 強行給出代碼 1 #include<stdio.h> 2 #include<string.h> 3 int head[11000],F[11000],w[11000],ass,stack[11000],n,point,m,D[11000],ans; 4 int min(int x,int y) 5 { 6 return x>y?y:x; 7 } 8 bool f[11000]; 9 struct shit{ 10 int aim,next,from; 11 }e[51000]; 12 int T,time[51000],dfn[51000]; 13 void tarjan(int x) 14 { 15 time[x]=dfn[x]=++T; 16 f[x]=true; 17 stack[++ass]=x; 18 for(int k=head[x];k;k=e[k].next) 19 { 20 int v=e[k].aim; 21 if(!time[v]) 22 { 23 tarjan(v); 24 dfn[x]=min(dfn[x],dfn[v]); 25 } 26 else if(f[e[k].aim])dfn[x]=min(dfn[x],time[v]); 27 } 28 if(dfn[x]==time[x]) 29 { 30 f[x]=false; 31 while(stack[ass]!=x) 32 { 33 w[x]++; 34 F[stack[ass]]=x; 35 f[stack[ass--]]=false; 36 } 37 ass--; 38 } 39 } 40 void fuck(int x,int y) 41 { 42 e[++point].aim=y; 43 e[point].from=x; 44 e[point].next=head[x]; 45 head[x]=point; 46 } 47 int main() 48 { 49 int a,b; 50 scanf("%d%d",&n,&m); 51 for(int i=1;i<=m;++i) 52 { 53 scanf("%d%d",&a,&b); 54 fuck(a,b); 55 } 56 for(int i=1;i<=n;++i)F[i]=i,w[i]=1; 57 for(int i=1;i<=n;++i) 58 if(!time[i])tarjan(i); 59 memset(head,0,sizeof(head)); 60 point=0; 61 for(int i=1;i<=m;++i) 62 { 63 if(F[e[i].from]==F[e[i].aim])continue; 64 else { 65 D[F[e[i].from]]++; 66 fuck(F[e[i].aim],F[e[i].from]); 67 } 68 } 69 for(int i=1;i<=n;i++) 70 if(F[i]==i&&!D[i])ans+=w[i]; 71 printf("%d",ans); 72 return 0; 73 } View Code沒什么好PS的
轉載于:https://www.cnblogs.com/PencilWang/p/5914366.html
總結
以上是生活随笔為你收集整理的简单tarjan》一道裸题(BZOJ1051)(easy)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何让你的webapp也能跳窗口搜索
- 下一篇: Filter 字符编码Filter 一