[拓扑排序]奖金

奖 金 奖金


题目描述

由于无敌的凡凡在 2005 2005 2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
  于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为 100 100 100元。


输入

两个整数 n , m n,m n,m,表示员工总数和代表数;
以下 m m m行,每行2个整数 a , b a,b a,b,表示某个代表认为第 a a a号员工奖金应该比第 b b b号员工高。


输出

若无法找到合法方案,则输出“ − 1 -1 1”;否则输出一个数表示最少总奖金。


样例输入

2 1
1 2


样例输出

210


题目解析

看题目,我们就想到了拓扑排序,以入度为 0 0 0的员工起手,用DP来计算员工的奖金

本题解使用链接表


code

#include<stdio.h>
#include<iostream>
#include<algorithm> 
using namespace std;
long long n,m,x1,y1,tot;
long long ans=0,head[10005],f[10005],c[10005],p[10005],du[10005];
struct node
{
	long long to,next;
}a[40005];
void add(long long x,long long y)
{
	a[++tot]=(node){y,head[x]};
	head[x]=tot;
}
void tp()
{
	long long t=0,h=0;
	for(long long i=1;i<=n;++i)
	 if(du[i]==0)
	 {
	 	p[++t]=i;
	 	c[i]=1;
	 }
	while(h<t)
	{
		++h;
		for(long long i=head[p[h]];i;i=a[i].next)
		{
			if(c[a[i].to]==0)
			{
				f[a[i].to]=max(f[a[i].to],f[p[h]]+1);
				--du[a[i].to];
				if(du[a[i].to]==0)
				{
					c[a[i].to]=1;
					p[++t]=a[i].to;
				}
			}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(long long i=1;i<=m;++i)
	{
		scanf("%d%d",&x1,&y1);
		du[x1]++;
		add(y1,x1);
	}
	for(long long i=1;i<=n;++i)f[i]=100;
	tp();
	for(long long i=1;i<=n;++i)
	{
		if(du[i]!=0)
		{
			printf("-1");
			return 0;
		}
		ans+=f[i];
	}
	printf("%d",ans);
}

posted @ 2020-08-18 11:19  unknown_future  阅读(104)  评论(0编辑  收藏  举报