08年东莞特长生 奖金
题目
由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出, 总经理心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
于是下令召开方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工的奖金应该比高!”决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。
输入
两个整数,,表示员工总数和代表数;
以下行,每行2个整数,,表示某个代表认为第号员工奖金应该比第号员工高。
输出
若无法找到合法方案,则输出“-1”;否则输出一个数表示最少总奖金。
样例
input
2 1
1 2
output
1
数据范围
80的数据满足<=1000,<=2000;
100的数据满足<=10000,<=20000。
解题思路
拓扑排序
SPFA求最长路径
当前点入度为0则入队
最后答案为所有最长路径的累加和
若图中有环,则输出*-1*
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,x,y,ans;
int f[52000],rd[52000],head[52000],dis[52000];
struct c{
int to,next;
}a[25000];
int main()
{
memset(dis,-0x7f,sizeof(dis));
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
a[i].to=x;
a[i].next=head[y];
head[y]=i; //x的工资比y高
rd[x]++; //统计入度
}
int h=0,t=0;
for (int i=1;i<=n;i++)
if (rd[i]==0) //入度为0
{
t++;
dis[i]=100; //工资为初值100
f[t]=i; //入队
}
do{
h++;
for (int i=head[f[h]];i;i=a[i].next)
{
rd[a[i].to]--; //入度-1
dis[a[i].to]=max(dis[a[i].to],dis[f[h]]+1); //SPFA最长路径
if (rd[a[i].to]==0) //入度为0,入队
{
t++;
f[t]=a[i].to;
}
}
}while(h<t);
for (int i=1;i<=n;i++)
{
if (rd[i]>0) //入度>0,存在环,输出-1
{
cout<<-1;
return 0;
}
ans+=dis[i]; //累加最长路径
}
cout<<ans<<endl;
return 0;
}
来源:CSDN
作者:ssl_yty
链接:https://blog.csdn.net/qq_45621109/article/details/104025090