题目描述
由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。
输入格式
第一行两个整数n,m,表示员工总数和代表数;
以下m行,每行2个整数a,b,表示某个代表认为第a号员工奖金应该比第b号员工高。
输出格式
若无法找到合理方案,则输出“Poor Xed”;否则输出一个数表示最少总奖金。
样例输入
2 1
1 2
样例输出
201
代码 + 分析
和往常一样,详解就附在代码上了。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 10005;
vector <int> G[MAXN];
queue <int> q;
int tot[MAXN];
int cost[MAXN];
int len = 1;
int n, m;
void topsort () {
for (int i = 1; i <= n; i++) {
if (!tot[i]) {
q.push (i);
}//假如这个点没有度(前驱),就把他入队
cost[i] = 100;//题目所说,工资最少为 100
}
//就是常规操作
while (!q.empty()) {
int x = q.front ();//取出队头
q.pop();//弹出
len ++;//答案的长度累加
for (int i = 0; i < G[x].size(); i++) {
if (tot[G[x][i]]) { //假如与它相连的还有没处理完的
tot[G[x][i]] --;//那么就应该把他的度减少一个(比他先处理的人要少一个)(因为我们是从小往大求的)
if (tot[G[x][i]] == 0) {//假如他就是下一个要处理的人
q.push (G[x][i]);//就把他装进队列,继续搜索
cost[G[x][i]] = max(cost[G[x][i]], cost[x] + 1);//他的答案应该就等于上一个人的钱数加 1 块钱
}
}
}
}
}
int main() {
scanf("%d %d", &n, &m);//输入
for (int i = 1; i <= m; i++) {
int x, y;
scanf("%d %d", &x, &y);
G[y].push_back(x);//假如 x 比 y 多,那么 x 就应该在 y 的后面,所以把 x 存进 y 里
tot[x] ++;//x 的度累加
}
topsort ();//拓扑
if (len < n) {
printf("Poor Xed
");
return 0;
}//假如答案的长度还没有 n ,那么说明无解
int sum_ = 0;
for (int i = 1; i <= n; i++) {
sum_ += cost[i];
}//累加答案
printf("%d", sum_);//完美结束
return 0;
}