标签
拓扑排序好题
题目描述
由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。
AC艰难历程
-
20
20
20 分:看着眼熟打了一个差分约束
- 错误原因:未知,反正是挂了
- 10 10 10 分:回炉重造了一遍差分约束,又挂了……
- 100 100 100 分:然后我改成了拓扑……
题解
思路
如果 A 比 B 大,则 B 向 A 指一条有向边;
在拓扑排序的同时统计答案。
证明
略
代码
#include <bits/stdc++.h>
#define ios \
ios::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0)
// #pragma GCC optimize(2)
#define ll long long
#define pll pair<ll, ll>
#define pii pair<int, int>
#define il inline
#define p_q priority_queue
#define u_m unordered_map
using namespace std;
vector<int> G[10005];
int n, m;
int dis[10005];
int Used[10005];
bool Top(int Start) {
queue<int> q;
for (int i = 1; i <= n; i++) if (!Used[i]) q.push(i);
int num = 0;
while (!q.empty()) {
int tmp = q.front();
q.pop();
num++;
for (int i = 0; i < G[tmp].size(); i++) {
Used[G[tmp][i]]--;
if (Used[G[tmp][i]] == 0) {
q.push(G[tmp][i]);
}
dis[G[tmp][i]] = max(dis[tmp] + 1, dis[G[tmp][i]]);
}
}
return n == num;
}
int main() {
ios;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int a, b;
cin >> a >> b;
G[b].push_back(a);
Used[a]++;
}
if (!Top(0)) {
cout << "Poor Xed";
return 0;
}
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += dis[i] + 100;
}
cout << ans;
return 0;
}