ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【C++】ZZ1765- 解题精讲

2022-06-11 22:33:10  阅读:197  来源: 互联网

标签:ZZ1765 个点 int 精讲 C++ 选手 111 营员 编号


【Horn Coding Studio】CPP编程专栏

题目

题目描述

最近美团举办了一场编程比赛。在赛场上,参赛者们按1..N依次编号。每位参赛者的编程能力不尽相同,参赛者们的编程能力有明确的排名。 整个比赛被分成了若干轮,每一轮是两名指定编号的选手的对决。如果编号为A的的选手编程能力强于编号为B的选手(1 <= A <= N; 1 <= B <= N; A != B) ,那么在对决中,编号为A的选手总是能胜出。 美团想知道选手们编程能力的具体排名,于是美团找来了选手们所有 M(1 <= M <= 4,500)轮比赛的结果,希望你能根据这些信息,推断出尽可能多的选手的编程能力排名。比赛结果保证不会自相矛盾。

输入

第1行: 2个用空格隔开的整数:N 和 M

第2..M+1行: 每行为2个用空格隔开的整数A、B,描述了参加某一轮比赛的选手的编号,以及结果(编号为A,即为每行的第一个数的选手为胜者)

输出

第1行: 输出1个整数,表示排名可以确定的选手的数目

样例输入 复制

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

样例输出 复制

2

提示

输出说明:

编号为2的选手输给了编号为1、3、4的选手,也就是说他的水平比这3名选手都差。而编号为5的选手又输在了他的手下,也就是说,他的水平比编号为5的选手强一些。于是,编号为2的选手的排名必然为第4,编号为5的选手的水平必然最差。其他3名选手的排名仍无法确定。

来源

一点即通

对于每个美团骑手,将其假设为一个点,假如所有点与它的关系都确定了,那么它的排名也就确定了。什么意思呢?就是,比如1、2可以到3,3可以到4、5,那么无论前面的1、2,还是后面的4、5的排位改变都不关3的事,3始终是排第三,(1-2-3-5-4或者2-1-3-4-5)。所以,我们可以把这题奶牛看成是地图上的n个点,f[i][j]表示第i个点可以到达第j个点,f[i][j]=f[i][k]&&f[k][i]表示为第i个点可以通过第k个点到达第j个点。这就是floyd算法的变形。

编号为2的营员输给了编号为1、3、4的营员,也就是说他的水平比这3名营员都差。而编号为5的营员又输在了他的手下,也就是说,他的水平比编号为5的营员强一些。于是,编号为2的营员的排名必然为第4,编号为5的营员的水平必然最差。其他3名营员的排名仍无法确定。
思路:要确定一个人的名次,只看在他前面多少人,在他后面多少人,若为n-1,则可以确定。

代码

ZZOJ     AC     

LuoguOJ     *没有这道题目

#include <bits/stdc++.h>
using namespace std;
vector<int>e1[111];
vector<int>e2[111];
int ans1[111];
int ans2[111];
bool vis[111];

int dfs1(int x) {
    int siz = e1[x].size ();
    int ans = 0;
    for(int i=0;i<=siz-1;i++) {
        int v = e1[x][i];
        if(vis[v]) continue;
        vis[v]=1;
        ans++;
        ans+=dfs1 (v);
    }
    return ans;
}
 
int dfs2(int x) {
    int siz = e2[x].size ();
    int ans = 0;
    for(int i=0;i<=siz-1;i++){
        int v = e2[x][i];
        if(vis[v]) continue;
        vis[v]=1;
        ans++;
        ans+=dfs2 (v);
    }
    return ans;
}
 
int main () {
    int n,m;
    cin>>n>>m;
    while (m--) {
        int a,b;
        cin>>a>>b;
        e1[a].push_back (b);
        e2[b].push_back (a);
    }
    for(int i=1;i<=n;i++) {
        vis[i]=1;
        ans1[i]=dfs1 (i);
        memset (vis,0, sizeof (vis));
    }
    for(int i=1;i<=n;i++){
        vis[i]=1;
        ans2[i]=dfs2(i);
        memset (vis,0, sizeof (vis));
    }
    int ans = 0;
    for(int i=1;i<=n;i++) {
        if(ans1[i]+ans2[i]==n-1) {
            ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

标签:ZZ1765,个点,int,精讲,C++,选手,111,营员,编号
来源: https://www.cnblogs.com/Kelwen/p/Horn_Coding_Studio_CodeBlogs_6_Cpp.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有