HDU 2647 Reward(拓扑排序)

原创 2016年05月31日 15:26:28

Reward

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7049    Accepted Submission(s): 2192


Problem Description
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

分析:拓扑排序,判断有向五环图。入度为0的结点跳出结点集合,根据结点在哪一次跳出结点集合决定需要花费的钱,即888+top-1(第一个结点为888),根据跳出的结点数,来判断是否有环存在。

代码如下:

#include <stdio.h>
#include <vector>
#include <string.h>
#define MAX 10010
using namespace std;
int n,m;
int money[MAX];
int vis[MAX],indegree[MAX],f[MAX];
int sum=0,top,t;
vector <int>map[MAX];
void init()
{
	for(int i=1;i<MAX;i++)
		map[i].clear();		//清空邻接表 
	for(int i=0;i<MAX;i++)
		money[i]=888;		//初始工资 
	memset(indegree,0,sizeof(indegree)); 	//入度清零
	memset(f,0,sizeof(f));
	top=0;	//层数清零
	t=0;	//访问结点数清零 
}

void toposort()
{
	int i,j,k;
	bool p;
	p=true;
	while(p)
	{
		p=false;
		top++;
		for(i=1;i<=n;i++)
		{
			if(!indegree[i])
			{
				p=true;
				f[i]=top;
				money[i]=money[i]+top-1;
				t++;
			}
		}
		for(i=1;i<=n;i++)
		{
			if(f[i]==top)
			{
				for(k=0;k<map[i].size();k++)
				{
					int v=map[i][k];
					indegree[v]--;
				}
				indegree[i]=-1;
			}
		}
	}
	top--;
}

int main()
{
	int i,j;
	int a,b;
	while(~scanf("%d %d",&n,&m))
	{
		init();
		for(i=1;i<=m;i++)
		{
			scanf("%d %d",&a,&b);
			map[b].push_back(a);
			indegree[a]++;
		}
		toposort();		
		if(t==n)
		{
			int sum=0;
			for(i=1;i<=n;i++)
				sum+=money[i];
			printf("%d\n",sum);
		}
		else
			printf("-1\n");
	}
	
	return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu Reward(拓扑排序)

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S...

HDU 2647 Reward(图论-拓扑排序)

HDU 2647 Reward(图论-拓扑排序) 题目大意: n个人,m条边,每条边a,b 表示a比b的工资多1,每个人的工资至少888,问你工资和至少多少?如果出现矛盾关系,输出-1 解题思路:...

HDU 2647 Reward(图论-拓扑排序)

题目大意: n个人,m条边,每条边a,b 表示a比b的工资要多,每个人的工资至少888,问满足关系的工资总和至少多少?如果出现关系矛盾,输出-1 解题思路: 根据工资关系建立拓扑图,0入度的人工资从8...
  • wujy47
  • wujy47
  • 2014年08月03日 17:08
  • 588

hdu2647 Reward(拓扑排序)

老板要给很多员工发奖金, 但是部分员工有个虚伪心态, 认为自己的奖金必须比某些人高才心理平衡 输入若干个关系 a b a c c b 意味着a 的工资必须比b的工资高 同时a 的工资比c高; c的工资...
  • ygqwan
  • ygqwan
  • 2013年09月19日 09:35
  • 1781

HDU2647 Reward(拓扑排序)反向建图

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S...

HDU:2647 Reward(链表型拓扑排序)

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S...
  • zugofn
  • zugofn
  • 2016年08月05日 21:20
  • 140

HDU 2647 Reward (拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 题面: Reward Time Limit: 2000/1000 MS (...

HDU-2647 Reward(拓扑排序)

第一道拓扑排序题目,很简单,但是书上讲的是用栈实现的,不会应用在这道需要分层的题,看了别人用队列实现的感觉很简单易懂,便按照类似的思路写了一次,效率貌似有点低,毕竟用了vector和队列,还需要更多的...

HDU 2647 Reward(拓扑排序)

原题链接:Here! 分析:因为最近一直在做拓扑排序的问题,所以没多想就采用拓扑排序来解决这个问题,后来一想,跟并查集好像...... 1.判断图中是否存在环只需看能够处理多少节点,如果 处理节点数...

hdu 2647 Reward(拓扑排序)

RewardProblem Description Dandelion’s uncle is a boss of a factory. As the spring festival is comin...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU 2647 Reward(拓扑排序)
举报原因:
原因补充:

(最多只允许输入30个字)