奖金
ssl 1325
题目大意:
有n个人,某个人要比另外一个人的工资高(工资最低为100,最少多1元),问最少发多少工资
原题:
题目描述
由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。
输入
两个整数n,m,表示员工总数和代表数;
以下m行,每行2个整数a,b,表示某个代表认为第a号员工奖金应该比第b号员工高。
输出
若无法找到合法方案,则输出“-1”;否则输出一个数表示最少总奖金。
输出样例
2 1
1 2
输入样例
201
数据范围:
80%的数据满足n<=1000,m<=2000;
100%的数据满足n<=10000,m<=20000。
解题思路:
这就是拓扑排序,先按顺序拓扑排序一遍,中途顺便DP(以100为低值),因为要求最小所以一定是上一个数+1,然后有多个条件是就要求最大的
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,x,y,h,tot,sum,rd[10500],head[10500],ans[10500];
struct rec
{int to,next;
}a[20500];
void topsort()//拓扑排序
{queue<int>d;for (int i=1;i<=n;++i)if (!rd[i]) d.push(i),ans[i]=100;//入度为0的while(!d.empty()){h=d.front();d.pop();for (int i=head[h];i;i=a[i].next){rd[a[i].to]--;ans[a[i].to]=max(ans[h]+1,ans[a[i].to]);//取最大if (!rd[a[i].to])//入度为0{rd[a[i].to]--;d.push(a[i].to);}}}
}
int main()
{scanf("%d %d",&n,&m);for (int i=1;i<=m;++i){scanf("%d %d",&x,&y);a[++tot].to=x;a[tot].next=head[y];head[y]=tot;rd[x]++;}topsort();for (int i=1;i<=n;++i)if (rd[i]<=0) sum+=ans[i];//符合else{sum=-1;//存在环break;}printf("%d",sum);
}