• Floyd--P2419 [USACO08JAN]牛大赛Cow Contest


    *传送

      FJ的$N(1 <= N <= 100)$头奶牛们最近参加了场程序设计竞赛:)。在赛场上,奶牛们按1..N依次编号。每头奶牛的编程能力不尽相同,并且没有哪两头奶牛的水平不相上下,也就是说,奶牛们的编程能力有明确的排名。 整个比赛被分成了若干轮,每一轮是两头指定编号的奶牛的对决。如果编号为A的奶牛的编程能力强于编号为B的奶牛$(1 <= A <= N; 1 <= B <= N; A != B)$ ,那么她们的对决中,编号为A的奶牛总是能胜出。 FJ想知道奶牛们编程能力的具体排名,于是他找来了奶牛们所有 $M(1 <= M <= 4,500)$轮比赛的结果,希望你能根据这些信息,推断出尽可能多的奶牛的编程能力排名。比赛结果保证不会自相矛盾。

      看到$n<=100$按$floyd$的$n^3$做法还是可以的,毕竟$floyd$代码简略且少。

      首先思考这道题,怎样才能确定一头牛的名次,显然是他与其他所有牛的输赢关系都确定。因为只有输赢两种情况,所以我们只要记录赢得情况就可以。输入$a$和$b$,$s[a][b]=1$表示$a$赢了$b$。这样预处理之后,就开始跑$floyd$。$floyd$代码如下(下面有解释):

     1 void Floyd()
     2 {
     3     for (int t = 1;t <= n;t++)
     4     {
     5         for (int i = 1;i <= n;i++)
     6         {
     7             for (int j = 1;j <= n;j++)
     8             {
     9                 if (s[i][t]&&s[t][j])
    10                     s[i][j]=1;
    11             }
    12         }
    13     }
    14 }

    这里的t可以看做一个中转节点,如果i赢了t,且t赢了j,那么i就赢了j,这种简单逻辑还是可以推导出来的。然后我们就可以开始统计答案了。考虑一个问题,怎样知道两头牛之间的关系是否确定,s[i][j]=1表示i赢了j,两头牛的关系是确定的,s[j][i]=1表示j赢了i,两头牛的关系也是确定的,但是如果s[i][j]=0&&s[j][i]=0并不是说i输给了j,j输给了i,这显然是不成立的,而是根本没有确定。由于之前说过的,确定一头牛的名次根据是,他和所有牛的输赢关系都确定,所以只要有一个不确定我们就直接跳到下一个牛开始判断。这部分代码:

     1     for(int i = 1;i <= n;i++)
     2     {
     3         int f=1;
     4         for (int j = 1;j <= n;j++)
     5         {
     6             if (i==j)continue;
     7             if (s[i][j]==0&&s[j][i]==0)
     8             {
     9                 f=0;
    10                 break;
    11             }
    12         }
    13         if (f==1)
    14             ans++;
    15     }

    整个代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cmath>
     4 #include <iostream>
     5 #include <cstring>
     6 using namespace std;
     7 int n,m,a,b;
     8 int s[1000][1000];
     9 int read()
    10 {
    11     int x=1,a=0;
    12     char ch=getchar();
    13     while (ch < '0'||ch > '9')
    14     {
    15         if (ch == '-') x=-1;
    16         ch = getchar();
    17     }
    18     while (ch <= '9'&&ch >= '0')
    19     {
    20         a=a*10 + ch - '0';
    21         ch=getchar();
    22     }
    23     return x*a;
    24 }
    25 void Floyd()
    26 {
    27     for (int t = 1;t <= n;t++)
    28     {
    29         for (int i = 1;i <= n;i++)
    30         {
    31             for (int j = 1;j <= n;j++)
    32             {
    33                 if (s[i][t]&&s[t][j])
    34                     s[i][j]=1;
    35             }
    36         }
    37     }
    38 }
    39 int main()
    40 {
    41     int ans=0;
    42     n=read();
    43     m=read();
    44     for (int i = 1;i <= m;i++) 
    45     {
    46         a=read();
    47         b=read();
    48         s[a][b]=1;
    49     }
    50     Floyd();
    51     for(int i = 1;i <= n;i++)
    52     {
    53         int f=1;
    54         for (int j = 1;j <= n;j++)
    55         {
    56             if (i==j)continue;
    57             if (s[i][j]==0&&s[j][i]==0)
    58             {
    59                 f=0;
    60                 break;
    61             }
    62         }
    63         if (f==1)
    64             ans++;
    65     }
    66     cout<<ans;
    67     return 0;
    68 }
  • 相关阅读:
    Ubuntu上安装Redis
    Unity Shader中将指定颜色过滤成透明
    用Python发送邮件
    Flask搭建简单的服务器
    SQLServer 中All、Any和Some用法与区别
    Linux探秘之用户态与内核态
    MTDDL 美团点评分布式数据访问层中间件
    基础数据结构 例:栈、队列、链表、数据、字典、树、等
    二叉树、红黑树、B&B+树数据结构
    CPU,GPU,高速缓存cache,内存RAM,虚拟内存VM,磁盘ROM,磁盘缓存之间的关系
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12323830.html
Copyright © 2020-2023  润新知