【问题描述】
某班级有 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;
}