1192. 獎金(拓撲排序)

題目:
由於無敵的凡凡在2005年世界英俊帥氣男總決選中勝出,Yali Company總經理Mr.Z心情好,決定給每位員工發獎金。

公司決定以每個人本年在公司的貢獻爲標準來計算他們得到獎金的多少。

於是Mr.Z下令召開 m 方會談。

每位參加會談的代表提出了自己的意見:“我認爲員工 a 的獎金應該比 b 高!”

Mr.Z決定要找出一種獎金方案,滿足各位代表的意見,且同時使得總獎金數最少。

每位員工獎金最少爲100元,且必須是整數。

輸入格式
第一行包含整數 n,m,分別表示公司內員工數以及參會代表數。

接下來 m 行,每行 2 個整數 a,b,表示某個代表認爲第 a 號員工獎金應該比第 b 號員工高。

輸出格式
若無法找到合理方案,則輸出“Poor Xed”;

否則輸出一個數表示最少總獎金。

數據範圍
1≤n≤10000,
1≤m≤20000
輸入樣例:
2 1
1 2
輸出樣例:
201

分析:a比b錢多,因爲能確定下限,就將其改爲b比a錢少,就可以存儲一條邊add(b,a),接下來差不多裸的拓撲排序,用一個dis數組存那個人的獎金爲多少,最先入度爲0的人獎金爲100,在中間處理的時候某個點入度爲0時,它的dis[j] = dis[t]+1,有環的話會少於總人數,最後返回處理個數是否等於已有人數。

c++代碼如下:

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 1e9+7;
const int N = 20010;

int n,m,in[N];
queue<int> qe;
int e[N],ne[N],h[N],idx=1;
int dis[N];

void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

bool top_sort()
{
	int con = 0;
	for(int i=1;i<=n;i++)
		if(in[i] == 0)
		{
			dis[i] = 100;
			qe.push(i);
			con++;
		}
	while(qe.size())
	{
		int t = qe.front();
		qe.pop();
		for(int i=h[t];i;i=ne[i])
		{
			int j = e[i];
			in[j] -- ;
			if(!in[j])
			{
				con ++ ;
				dis[j] = dis[t] + 1;
				qe.push(j);
			}
		}
	}
	return con == n;
}

int main(){
//	IOS;
	#ifdef ddgo
		freopen("C:\\Users\\asus\\Desktop\\ddgoin.txt","r",stdin);
	#endif
	
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int a,b;  scanf("%d %d",&a,&b);
		add(b,a);
		in[a] ++;
	}
	
	if(top_sort())
	{
		int sum = 0;
		for(int i=1;i<=n;i++)
			sum += dis[i];
		printf("%d\n",sum);
	}
	else puts("Poor Xed");
	
	return 0;
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章