欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HDU 2647 Reward(拓扑排序)

程序员文章站 2024-03-13 23:35:16
...

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.
InputOne 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. OutputFor 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

题意:

老板要给每个员工发工资,每个员工的工资至少要有888,但是有的员工提出了别的要求,每一行要求的a,b表示:a的工资要比b的工资高。根据那些要求算出老板所要支付的最少工资。

因为数据上w,所以邻接矩阵空间不够,用了邻接表,同时拓扑排序的时候,记得反向建表。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int mx = 21000;
int head[mx], cnt, value[mx], in[mx];
int n, m;
struct node{
	int u, v, next;
} edge[mx];
void add(int u, int v){
	edge[cnt].u = u;
	edge[cnt].v = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
void init(){
	cnt = 0;
	memset(head, -1, sizeof(head));
	memset(value, 0, sizeof(value));
	memset(in, 0, sizeof(in));
}
int topu(){
	queue<int>q;
	while(!q.empty()) q.pop();
	int co = 0, sum =0;
	for(int i = 1; i <= n; i++){
		if(in[i] == 0){
			q.push(i);
			co++;
		}
	}
	int fr;
	while(!q.empty()){
		fr = q.front();
		q.pop();
		for(int i = head[fr]; i != -1; i = edge[i].next){
			int u = edge[i].u, v = edge[i].v;
			in[v]--;
			if(in[v] == 0){ 
				value[v] = value[u] + 1;
				sum += value[v];
				q.push(v); 	
				co++; 
			}	
		}
	}
	
	if(co == n) return sum + n * 888 ;
	else return -1;
	
}

int main(){
	int a, b;
while(scanf("%d%d", &n,&m) != EOF){
	init();
	while(m--){
		scanf("%d%d", &b, &a);		//反向建图 
		add(a, b);
		in[b]++;
	}
	
	printf("%d\n",topu());
	
}

return 0;} 


相关标签: 拓扑