2974. 排名_拓扑排序

【问题描述】

某班级有 n 个学生,现在老师决定按成绩名次决定学生是否及格。

老师只给出 m 条关系:a > b ,代表学生 a 的成绩大于学生 b。

因此学生们需要自己计算自己的排位。

数据保证最终能确定 n 个学生的总排名。

不能确定总排名的例子:3 个学生,只给出 2 条关系,a > b,a > c,我们无法判断 b 和 c 的排名。

能确定总排名的例子:4个学生,给出 4 条关系,a > c,c > d,d > b,a > d,我们能确定最终排名为 a > c > d > b。

【输入格式】

第一行,两个整数 n (1 <= n <= 10000),m (n - 1 <= m <= 1000000),表示有 n 个学生,m 条关系。

接下来 m 行,每行 2个整数 a,b 表示 学生 a 的成绩大于学生 b(1 <= a, b <= n)。

【输出格式】

一行,n个整数,第 i 个整数表示学生 i 的排名。

【样例输入】

4 4

1 3

3 4

4 2

1 4

【样例输出】

1 4 2 3

【样例说明】

最终排名为 1 > 3 > 4 > 2,所以学生 1 排第 1 名,学生 2 排第 4 名,学生 3 排第 2 名,学生 4 排第 3 名。

#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long ll;
vector<int>s[10240];
int cnt[10240] = {0}, ans[10240];
int main()
{
//    system("chcp 65001");
    cin.tie(0);
    cout.tie(0);
//    freopen("C:/Users/zhaochen/Desktop/input.txt", "r", stdin);
    int n, m;
    cin >> n >> m;
    while(m--)
    {
        int a,b;
        cin >> a >> b;
        s[a].push_back(b);   // 在a后面添加b,表示a>b
        cnt[b]++;            // 比b大的人的数量
    }
    int rank = 1, cur;
    for(int i = 1; i <= n; i++)
    {
        if(cnt[i] == 0)      // 没有出现比i大的
        {
            cur = i;
            break;
        }
    }
    while(s[cur].size())	     // 还有比cur小的
    {
        ans[cur] = rank++;	     // cur是第rank名
        int flag;
        for(int i = 0; i < s[cur].size(); i++)
        {
            int t = s[cur][i];	 // 对于每一个比cur小的人
            cnt[t]--;		     // 比他大的人的数量-1
            if(cnt[t] == 0)	     // 如果没有比他大的人了
            {
                flag = t;
            }
        }
        cur = flag;			     // 更新cur
    }
    ans[cur] = n;			     // 最后一名
    for(int i = 1; i <= n; i++)
    {
        cout << ans[i] << " ";
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值