题目大意:有一种关系a,b代表a的奖金比b的高,最少的奖金为888,求总共需要的最少的
钱数,让所有满足关系的人都得到应有的奖金,否则输出-1;
思路:反向进行拓扑,主要是统计奖金。
注意可能给定的数据是深林,所以可以先统计出度为0的点赋值为888,然后边拓扑边统计。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define ll __int64
using namespace std;
int head[20010],cnt,du[20010],p[20010];
struct node
{
int to,next;
}q[20010];
int n,reward[20010];
void topo()
{
int i,j,k;
queue<int>qu;
for(i=1;i<=n;i++)
{
if(du[i]==0)
{
reward[i]=888;
qu.push(i);
}
}
int t,sum=0;
while(!qu.empty())
{
t=qu.front();
qu.pop();
sum++;
for(k=head[t];k!=-1;k=q[k].next)
{
du[ q[k].to ]--;
if(!du[ q[k].to ])
{
reward[q[k].to ]=reward[t]+1;
qu.push(q[k].to );
}
}
}
if(sum!=n)
{
printf("-1\n");return ;
}
ll ans=0;
for(i=1;i<=n;i++)
{
ans+=reward[i];
}
printf("%lld\n",ans);
}
int main()
{
int m,i,j,k;
while(~scanf("%d%d",&n,&m))
{
int a,b;
cnt=1;
memset(head,-1,sizeof(head));
memset(du,0,sizeof(du));
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
q[i].to=a;
q[i].next=head[b];
head[b]=cnt++;
du[a]++;
}
topo();
}
return 0;
}