hdu2647 reward

    题目链接    hdu2647 reward

【题意】老板给工人发工资,但是工人有要求,有n个工人,m个要求,输入n,m接下来有m 行,代表m个要求,输入a,b代表a的工资要比b的工资高.每个工人最低工资888,求老板至少要发多少钱

【思路】拓扑排序,但是用邻接矩阵内存不够,可以用链式前向星或邻接表,这里有个陷阱就是前面工资比后面高,建图不能将关系搞错,否则WA。

链式前向星跟vector写的

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
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

int n,head[20008],money[10009],m,cnt,rudu[10009];
struct node{
	int v,next;
}edge[20008];
void add(int u,int v){
	edge[cnt].v =v;
	edge[cnt].next =head[u];
	head[u]=cnt++;	
}
void toposort(){
	int sum=0;
	for(int i=1;i<=n;++i){//遍历n个节点
		for(int j=1;j<=n;++j){//再次遍历,是为了下面rudu--时出现新的rudu为0的
			if(!rudu[j]){
				rudu[j]--;勿忘
				sum++;//记录是否有环
				for(int k=head[j];k;k=edge[k].next ){//变的方向是j->edge[k].v,k是个编号
					rudu[edge[k].v ]--;//不要忘记 
					if(money[edge[k].v ]-money[j]<1)//
					money[edge[k].v ]=money[j]+1;//思考
				}
			}
		}
	}
	if(sum!=n) printf("-1\n");//有环
	else{
		sum=0;
		for(int i=1;i<=n;++i)
		sum+=money[i]+888;
		printf("%d\n",sum);
	}
}
int main(){
	int a,b;
	while(scanf("%d%d",&n,&m)!=EOF){
		memset(head,0,sizeof(head));//每次都要初始化 
		memset(money,0,sizeof(money));
		memset(rudu,0,sizeof(rudu));
		cnt=1;//head初始化0(或-1),cnt则为1(或0),
		while(m--){
			scanf("%d%d",&a,&b);
			add(b,a);//建图b->a,(a->b意义不相同)
			rudu[a]++;
		}
		toposort();
	}
}
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<string.h>
using namespace std;
vector<int>V[10008];//V[]是个数组,有固定长度,vector<int>没有固定的长度
int money[10008],rudu[10008];

int n,m;
void topo(){
	int sum=0;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			if(!rudu[j]){
				rudu[j]--;
				sum++;
				for(int k=0;k<V[j].size() ;++k){
					rudu[V[j][k]]--;//V[j][k]的值是j->节点a,值是a
					if(money[V[j][k]]-money[j]<1)
					money[V[j][k]]=money[j]+1;
				}
				break;
			}
		}
	}
	//printf("%d\n",sum);
	if(sum!=n) printf("-1\n");
	else{
		sum=0;
		for(int i=1;i<=n;++i)
		sum+=888+money[i];
		printf("%d\n",sum);
	}
}
int main(){
	while(scanf("%d%d",&n,&m)!=EOF){
		int a,b;
		memset(money,0,sizeof(money));
		memset(rudu,0,sizeof(rudu));
		while(m--){
			scanf("%d%d",&a,&b);
			V[b].push_back(a);//方向b->a,V[b][a]没有赋边权的情况下,默认值为a,如果赋值的话就是边权了
			 rudu[a]++;
		}
		topo();
		for(int i=0;i<=n;++i)//每次都要清空,否则会保存上次的值
		V[i].clear() ;
	}	
}

猜你喜欢

转载自blog.csdn.net/weixin_42382758/article/details/82594534