HDU——2647【发奖金】

【题意】:

就是有一个老板,给自己的工人发奖金,起步888,而且,a要比b领得多,问你怎么发才能发最少的钱(自己不亏的 jian 商);

【思考】:

可以建个图,用拓扑,找到它们的入度,加上888就是那个最多的是最小的钱;这里有两种建图,重要思想还是拓扑。。。

Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards. 
The workers will compare their rewards ,and some one may have demands of the distributing of rewards ,just like a's reward should more than b's.Dandelion's unclue wants to fulfill all the demands, of course ,he wants to use the least money.Every work's reward will be at least 888 , because it's a lucky number.

Input

One line with two integers n and m ,stands for the number of works and the number of demands .(n<=10000,m<=20000) 
then m lines ,each line contains two integers a and b ,stands for a's reward should be more than b's.

Output

For every case ,print the least money dandelion 's uncle needs to distribute .If it's impossible to fulfill all the works' demands ,print -1.

Sample Input

2 1
1 2
2 2
1 2
2 1

Sample Output

1777
-1

ac代码一(vector版):

#include<cstring>
#include<cstdio>
#include<vector>

using namespace std;

const int maxn=2e4+10;

vector<int>v[maxn];
int money[maxn],vis[maxn],ans;
int n,m;

void topu_sort()
{
	ans=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(!vis[j]){
				vis[j]--;
				ans++;
				for(int k=0;k<v[j].size();k++)
				{
					vis[v[j][k]]--;
					if(money[v[j][k]]-money[j]<1)
						money[v[j][k]]=money[j]+1;;	
				}
			}
		}
	}
	if(ans!=n)	printf("-1\n");
	else{
		ans=0;
		for(int i=1;i<=n;i++)
			ans+=888+money[i];
		printf("%d\n",ans);
	}
}

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF){
		memset(money,0,sizeof(money));
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=m;i++)
		{
			int a,b;
			scanf("%d%d",&b,&a);
			v[a].push_back(b);
			vis[b]++;
		}
		topu_sort();
		for(int i=0;i<=n;i++)
			v[i].clear();
	}
	
	return 0;
}

ac代码二(链式前向星版):

写这个代码的时候,建错图了,搞得懵懵的,多亏了我家的小仙女,唉,鄙人还是太菜了,多练练

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;


int head[20008],money[10008],vis[10008];
int n,m,ans;

struct node{
	int now,next;
}edge[20008];


int cnt;
void add(int u,int v){
	edge[cnt].now =v;
	edge[cnt].next =head[u];
	head[u]=cnt++;
}

void topu_sort()
{
	ans=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(!vis[j])
			{
				vis[j]--;
				ans++;
				for(int k=head[j];k!=0;k=edge[k].next)
					{
						vis[edge[k].now]--;
						if(money[edge[k].now]-money[j]<1)
							money[edge[k].now ]=money[j]+1;
					}
			}
		} 
	}
	if(ans!=n)	printf("-1\n");
	else{
		ans=0;
		for(int i=1;i<=n;i++)
			ans+=888+money[i];
		printf("%d\n",ans);
	}
}

int main(){
	while(scanf("%d%d",&n,&m)!=EOF){
		memset(money,0,sizeof(money));
		memset(vis,0,sizeof(vis));
		memset(head,0,sizeof(head));
		cnt=1;
		while(m--){
			int a,b;
			scanf("%d%d",&a,&b);
			add(b,a);
			vis[a]++;
		}
		topu_sort();
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/sf_yang35/article/details/82621857