【poj】3660 Cow Contest【floyd传递闭包】

来源:互联网 发布:下架黄耀明音乐知乎 编辑:程序博客网 时间:2024/05/19 12:16

题意:

给你一张合法拓扑图中的一些边,问你其中那些节点的rank是可以确定的,比如说给出A>C,B>C两条边,总共有ABC三个节点的话,C的位置是可以确定的,排在第三位,AB无法确定大小,故答案为1

题解:

之前有想到过一个点的入度出度之和为节点数-1的话,就成立了,但是在计算入度出度的时候,考虑到我传递关系,本来打算记录所有前驱,去重的,但感觉时间和空间复杂度过高,苦思冥想,最后还是百度了一下,看到了floyd求传递闭包这个非常神奇的概念,传递闭包是离散数学中的概念,即若<a,b>,<b,c>∈集合那么必有<a,c>∈集合,floyd真是个神奇的方法,之后就按照上面说的算下一个节点的入度出度之和是否为n-1即可


#include<cstdio>#include<cstring>using namespace std;const int N=105;bool g[N][N];int main(){    int n,m,ans,a,b;    while(scanf("%d%d",&n,&m)!=EOF){        memset(g,0,sizeof(g));        while(m--){            scanf("%d%d",&a,&b);            g[a][b]=1;        }        for(int k=1;k<=n;k++)            for(int i=1;i<=n;i++)                for(int j=1;j<=n;j++)                    if(g[i][k]&&g[k][j])g[i][j]=1;        ans=0;        for(int i=1;i<=n;i++){            int ret=0;            for(int j=1;j<=n;j++)                if(g[i][j]||g[j][i])ret++;            if(ret==n-1)ans++;        }        printf("%d\n",ans);    }    return 0;}


                                             
0 0
原创粉丝点击