• POJ3660 row contest Floyd 传递闭包


    题意:有n头牛,编号为1到n,牛比赛啦,现在给出其中一些牛的pk结果,问哪些牛的排名能够确定。

    输入 n  m

          a   b

    n头牛,给出m个比赛结果,

    a  b 表示a打赢了b

    一头牛,如果能够确定他的排名,则这头牛的入度和出度之和必定为n-1.

    dis[i][j] 为1时表示从i能够到达j,即i的排名在j的前面。为0 时表示i,j不能确定。

    a[i] 表示确定了排名在i前面的个数。

    b[i] 表示确定了排名在i后面的个数。

    首先用floyd扫一遍,确定了哪些点能够到达哪些点,

    再扫一遍,求出a,b数组的值,

    再扫一遍,找出满足a[i]+b[i]+1==n的点i的个数。

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=110;
     4 int dis[maxn][maxn];
     5 int a[maxn];
     6 int b[maxn];
     7 void floyd(int n)
     8 {
     9     for(int k=1;k<=n;k++)
    10         for(int i=1;i<=n;i++)
    11             for(int j=1;j<=n;j++)
    12                 dis[i][j]=dis[i][j]||(dis[i][k]&&dis[k][j]);
    13 }
    14 int query(int n)
    15 {
    16     for(int i=1;i<=n;i++)
    17         for(int j=1;j<=n;j++)
    18             if(i!=j&&dis[i][j]){
    19                 a[i]++;
    20                 b[j]++;
    21             }
    22     int ans=0;
    23     for(int i=1;i<=n;i++)
    24         if(a[i]+b[i]+1==n)
    25             ans++;
    26     return ans;
    27 }
    28 int main()
    29 {
    30     int n;
    31     while(scanf("%d",&n)!=EOF){
    32         int m,u,v;
    33         scanf("%d",&m);
    34         memset(dis,0,sizeof(dis));
    35         memset(a,0,sizeof(a));
    36         memset(b,0,sizeof(b));
    37         for(int i=1;i<=m;i++){
    38             scanf("%d%d",&u,&v);
    39             dis[u][v]=1;
    40         }
    41         floyd(n);
    42         printf("%d
    ",query(n));
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    超有爱的并查集
    写给想当程序员的朋友
    POJ 1961 字符串 KMP (i-next[i])
    POJ 2406 KMP算法next数组理解
    POJ 2387 Bellman双重边
    POJ 1917 字符串替换
    POJ 1062 坑爹的聘礼(枚举等级差选择性找边)
    Linux下libxml2的使用
    浙大pat 1003
    判定一棵二叉树是否是二叉搜索树
  • 原文地址:https://www.cnblogs.com/-maybe/p/4370112.html
Copyright © 2020-2023  润新知