POJ 3660 Cow Contest. (传递闭包)【Floyd】
<题目链接>
题目大意:
有n头牛, 给你m对关系(a, b)表示牛a能打败牛b, 求在给出的这些关系下, 能确定多少牛的排名。
解题分析:
首先,做这道题要明确,什么叫确定牛的排名。假设该牛被x头牛打败(直接或间接),同时它也有y头手下败将(直接或间接),当x+y=n-1时,即除这头牛本身外,其他所有的牛都为这头牛贡献了出度或者入度。即,当这头牛与其它所有的牛的输赢关系都确定时(直接或间接),这头牛的排名也就可以确定了。而题目只给出了一些牛的直接输赢关系,这时,我们就可以利用Floyed算法,得到牛群之间的间接输赢关系。
比如:a-->b ,b-->c ,则 a-->c,这种传递关系的思想,在Floyed 的三重循环中可以很轻易的体现,如果不明白就自己画图感受一下。
#include <cstdio> #include <cstring> int main(){ int n,m; while(scanf("%d %d",&n,&m)!=EOF){ int line[110][110]; //line[i][j] 表示 i 赢 j memset(line,0,sizeof(line)); for(int i=1;i<=m;i++){ int a,b; scanf("%d %d",&a,&b); line[a][b]=1; //输入的是能够直接确定输赢关系的点 } /* Floyed -传递闭包 */ //即,如果a-->b,b-->c的话,那么a-->c for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++){ if(line[j][i]&&line[i][k]){ line[j][k]=1; } } } } //用Floyed算法将那些间接的输赢关系也全部计算出来 int ans=0; for(int i=1;i<=n;i++){ bool flag=true; for(int j=1;j<=n;j++){ if(i==j)continue; if(!line[i][j]&&!line[j][i])flag=false; //如果除它自己以外,还存在不能够和它确定输赢的点(直接或间接),那么这个点的位置不能够确定 } if(flag){ ans++; } } printf("%d\n",ans); } return 0; }
2018-08-27
作者:is_ok
出处:http://www.cnblogs.com/00isok/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。