zoukankan      html  css  js  c++  java
  • Bzoj 1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名 传递闭包,bitset

    1703: [Usaco2007 Mar]Ranking the Cows 奶牛排名

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 323  Solved: 238
    [Submit][Status][Discuss]

    Description

        农夫约翰有N(1≤N≤1000)头奶牛,每一头奶牛都有一个确定的独一无二的正整数产奶率.约翰想要让这些奶牛按产奶率从高到低排序.    约翰已经比较了M(1≤M≤10000)对奶牛的产奶率,但他发现,他还需要再做一张关于另外C对奶牛的产奶率比较,才能推断出所有奶牛的产奶率排序.请帮他确定C的最小值.

    Input

        第1行包含两个用空格分开的整数N和M.接下来M行,每行有两个用空格分开的整数X和Y(1≤X,y≤1000),表示奶牛X的产奶率高于奶牛Y.

    Output

     
      C的最小值.

    Sample Input

    5 5
    2 1
    1 5
    2 3
    1 4
    3 4

    INPUT DETAILS:

    FJ is comparing 5 cows and has already determined that cow 2 > cow
    1, cow 1 > cow 5, cow 2 > cow 3, cow 1 > cow 4, and cow 3 > cow 4
    (where the '>' notation means "produces milk more quickly").

    Sample Output

    3

    HINT

        从输入样例中可以发现,约翰已经知道的排名有奶牛2>奶牛1>奶牛5和奶牛2>奶牛3>奶牛4,奶牛2排名第一.但是他还需要知道奶牛1的名次是否高于奶牛3来确定排名第2的奶牛,假设奶牛1的名次高于奶牛3.接着,他需要知道奶牛4和奶牛5的名次,假设奶牛5的名次高于奶牛4.在此之后,他还需要知道奶牛5的名次是否高于奶牛3.所以,他至少仍需要知道3个关于奶牛的排名.

    Source

    Gold

    题解:

    首先,看到每行为x大于y,可以想到我们可以把每行看为有向边x->y。然后在纸上画一画,我们发现,这道题其实要求的是有多少个点对(i,j) (1<=i,j<=n),满足i通过有向图中的边到不了j且j通过有向图的边也到不了i。之后就是直接用Warshall求传递闭包(其实跟floyd差不多,2333)。但是我们不能用三重循环求解,会超时。于是就想到用bitset优化即可。

    代码很短。。。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 bitset<1010> a[1010];
     4 int read()
     5 {
     6     int s=0,fh=1;char ch=getchar();
     7     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
     8     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
     9     return s*fh;
    10 }
    11 int main()
    12 {
    13     int n,m,x,y,k,i,j,ans;
    14     n=read();m=read();
    15     //for(i=1;i<=n;i++)a[i].reset();
    16     for(i=1;i<=m;i++)
    17     {
    18         x=read();y=read();
    19         a[x][y]=1;
    20     }
    21     //for(i=1;i<=n;i++)a[i][i]=1;
    22     for(i=1;i<=n;i++)
    23     {
    24         for(j=1;j<=n;j++)
    25         {
    26             if(a[j][i])a[j]|=a[i];//j既然能到i,那么也可以到i能到的所有点.
    27         }
    28     }
    29     ans=0;
    30     for(i=1;i<=n;i++)
    31     {
    32         for(j=i+1;j<=n;j++)
    33         {
    34             if(a[i][j]==0&&a[j][i]==0)ans++;
    35         }
    36     }
    37     printf("%d",ans);
    38     fclose(stdin);
    39     fclose(stdout);
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    机器学习个人总结
    yolo buffer is too small for requested array
    anaconda + VSCode + 生产环境配置
    YOLO.h5 下载
    通过爬虫程序深入浅出java 主从工作模型
    KafKa记录
    springboot 整合spark-sql报错
    机器学习项目笔记
    python学习笔记之入门
    django-5-使用数据库
  • 原文地址:https://www.cnblogs.com/Var123/p/5281580.html
Copyright © 2011-2022 走看看