题目链接:https://cn.vjudge.net/problem/HDU-2647
题目
老板发工资以及报酬,一共n个人,m个关系,每个关系中给出a和b,表示a的报酬要大于b的报酬,每个人的基本工资都是888元,问老板最少发多少工资。如果不能合理分配,输出-1。
分析
每输入一对a,b,就将a的度加1,然后拓扑排序就可以了。注意如果有环的话,那么一定不能合理分配。另外需要再开一个数组d[ ],表示每个人至少得到的报酬是多少,既然老板要支付最少的工资,那如果a比b的报酬多,多1元就可以了。
代码
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
int n,m,deg[100010];
ll d[100010];
vector<int> v[100010];
ll tpsort()
{
int cnt=0;
ll sum=0;
queue<int> q;
for(int i=1;i<=n;i++)
{
if(deg[i]==0)
{
cnt++;
q.push(i);
}
}
while(!q.empty())
{
int t=q.front();
q.pop();
for(int i=0;i<v[t].size();i++)
{
int num=v[t][i];
deg[num]--;
d[num] = max(d[num],d[t]+1);//至少得到的报酬
if(deg[num]==0)
{
cnt++;
q.push(num);
sum += d[num];//报酬和
}
}
}
if(cnt<n)
return -1;
return sum;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int a,b;
for(int i=0;i<=n;i++)
{
deg[i] = 0;
d[i] = 0;
v[i].clear();
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
deg[a]++;
v[b].push_back(a);
}
ll ans = tpsort();
if(ans==-1)
printf("-1\n");
else
printf("%lld\n",ans+(ll)(888*n));
}
return 0;
}