洛谷 P2419 [USACO08JAN]Cow Contest S(最短路:floyed)

https://www.luogu.com.cn/problem/P2419

题目大意:

给定n头奶牛(1<=N<=100),按1..N依次编号。

m轮:两两之间进行对决,赢了的排在左边,输了的排在右边。

我们想知道奶牛们编程能力的具体排名,希望能根据这些信息,推断出尽可能多的奶牛的编程能力具体排名。
输入 #1 
5 5
4 3
4 2
3 2
1 2
2 5
输出 #1 
2

一眼拓扑排序,但是拓扑实现起来应该会很麻烦,而且数据范围挺小的,所以我们可以换一种思维

  • 如果A赢了B,那么AB之间连接一条边;
  • 按最短路实现所有边的连接
  • 如果一个点,可以由其他所有点都有直接或者间接的连接,那么就可以确定具体的排名,
  • 否则不能确定具体的名次位置

对于题目给的样例一,我们可以画一个图

注意箭头指向

在这个样例中我们就可以很清晰得得出结论

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=2000020;
const int N=200200,M=2002;
LL f[M][M];
int main()
{
    cin.tie(0); cout.tie(0);ios::sync_with_stdio(false);
    LL T=1;
    //cin>>T;
    while(T--)
    {
        LL n,m;
        cin>>n>>m;
        for(LL i=1;i<=m;i++)
        {
            LL x,y;
            cin>>x>>y;
            f[x][y]=1;//表示x到y是联通的
        }
        for(LL k=1;k<=n;k++)
        {
            for(LL i=1;i<=n;i++)
            {
                for(LL j=1;j<=n;j++)
                {
                    //如果一开始就有路,如果两条路可以连接
                    f[i][j]=f[i][j]||(f[i][k]&&f[k][j]);
                }
            }
        }
        LL ans=0;
        for(LL i=1;i<=n;i++)
        {
            LL flag=1;
            for(LL j=1;j<=n;j++)
            {
                //对于任意节点 u,如果其他所有节点到节点 u 和从节点 u 到其他所有节点的路径都是确定的,那么节点 u 的排名就是确定的。
                if(i==j) continue;
                flag=flag&&(f[i][j]||f[j][i]);
            }
            if(flag==1) ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2022-09-30 20:47  Vijurria  阅读(98)  评论(0编辑  收藏  举报