hdu2647 Reward(拓扑排序)

老板要给很多员工发奖金, 但是部分员工有个虚伪心态, 认为自己的奖金必须比某些人高才心理平衡; 但是老板很人道, 想满足所有人的要求, 并且很吝啬,想画的钱最少

输入若干个关系

a b

a c

c b

意味着a 的工资必须比b的工资高 同时a 的工资比c高; c的工资比b高


当出现环的时候输出-1


思路: 反向建图, 然后top排序分层次; 第一次的工资为888(最低), 第二层的工资 + 1, 后面一样


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#pragma warning(disable: 4996)

using namespace std;

const int MaxV = 10003;
const int MaxE = 20003;

struct Graph
{
	void init()
	{
		top = 0;
		memset(head, -1, sizeof(head));
	}
	void addEdge(int u, int v)
	{
		next[top] = head[u];
		head[u] = top;
		num[top] = v;
		top++;
	}
	int top;
	int head[MaxV], num[MaxE], next[MaxE];
};

Graph g;
int in[MaxV];
int logicalTopSort(int vexNum)
{
	int tmp[MaxV], indexx = 0;
	memset(in, 0, sizeof(in));
	for(int i = 1; i <= vexNum; i++)
	{
		for(int j = g.head[i]; j != -1; j = g.next[j])
		{
			int v = g.num[j];
			in[v]++;
		}
	}

	int cengci = 0;
	int res = 0;
	for(int i = 1; i <= vexNum; i++)
	{
		int s = 1;
		bool flag = false;
		for(int j = 1; j <= vexNum; j++)
		{
			if(in[j] == 0)
				tmp[s++] = j;
			if(in[j] != -1)
				flag = true;
		}
		if(s == 1 && flag)
			return -1;
		res += ((s - 1) * (888 + cengci));
		cengci++;
		for(int j = 1; j < s; j++)
		{
			in[tmp[j]] = -1;
			for(int k = g.head[tmp[j]]; k != -1; k = g.next[k])
			{
				in[g.num[k]]--;
			}
		}
	}
	return res;
}

int main()
{
	//freopen("data_in.txt", "r", stdin);
	int vexNum, edgeNum;
	int u, v;
	while(scanf("%d %d", &vexNum, &edgeNum) != EOF)
	{
		g.init();
		for(int i = 0; i < edgeNum; i++)
		{
			scanf("%d %d", &u, &v);
			g.addEdge(v, u);
		}
		int ans = logicalTopSort(vexNum);
		printf("%d\n", ans);
	}
	return 0;
}

不知道为什么不会超时, 感觉这个题目必须得用队列优化为O(n + m); 否者为o(n * n); 优化的时候一定要注意什么时候入队, 否则容易多次入队, 还有就是要注意怎么判断不能排序成功的条件


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值