1352:【例4-13】獎金
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 4755 通過數: 1748
【題目描述】
由於無敵的凡凡在2005年世界英俊帥氣男總決選中勝出,Yali Company總經理Mr.Z心情好,決定給每位員工發獎金。公司決定以每個人本年在公司的貢獻爲標準來計算他們得到獎金的多少。
於是Mr.Z下令召開m方會談。每位參加會談的代表提出了自己的意見:“我認爲員工a的獎金應該比b高!”Mr.Z決定要找出一種獎金方案,滿足各位代表的意見,且同時使得總獎金數最少。每位員工獎金最少爲100元。
【輸入】
第一行兩個整數n,m,表示員工總數和代表數;
以下m行,每行2個整數a,b,表示某個代表認爲第a號員工獎金應該比第b號員工高。
【輸出】
若無法找到合理方案,則輸出“Poor Xed”;否則輸出一個數表示最少總獎金。
【輸入樣例】
2 1
1 2
【輸出樣例】
201
【提示】
【數據規模】
80%的數據滿足:n≤1000,m≤2000;
100%的數據滿足:n≤10000,m≤20000。
思路:
每次先查找入度爲0的點,放入隊列,然後取出它指向的那些點,把他們的工資+=目前入度爲0的點的工資-100(增值);然後將入度爲0的點刪除,對應的鄰接點入度減1;循環,不斷查找入度爲0的點,直到找不到爲止.
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define N 20005
using namespace std;
int n,m,tot = 0;
vector<int>p[N];
int in[N],pay[N],vis[N];
int topsort(){
queue<int>q;
for(int i = 1; i <= n;i++)
if(!in[i])
q.push(i);
int num = 0;
while(!q.empty()){
int u = q.front();
q.pop();
num++;
for(int i = 0; i < p[u].size();i++){
if(--in[p[u][i]] == 0){
q.push(p[u][i]);
}
pay[p[u][i]] = max(pay[u]+1,pay[p[u][i]]);
}
}
if(n == num) return true;
else return false;
}
int main(){
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i++)
{
pay[i] = 100;
}
memset(in,0,sizeof(in));
int x,y;
for(int i = 0; i < m; i++)
{
scanf("%d %d",&x,&y);
p[y].push_back(x);
in[x]++;
}
int sum = 0;
if(topsort()){
for(int i = 1; i <= n;i++)
{
sum += pay[i];
}
printf("%d\n",sum);
}
else printf("Poor Xed\n");
return 0;
}