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); 優化的時候一定要注意什麼時候入隊, 否則容易多次入隊, 還有就是要注意怎麼判斷不能排序成功的條件


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章