奖金
【例4-13】奖金
【问题描述】
由于无敌的凡凡在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
1 #include<cstdio> 2 using namespace std; 3 # define MAXN 20001 4 struct Edge 5 { 6 int vi; 7 int vj; 8 int next; 9 }; 10 struct Stack 11 { 12 int top; 13 int stack[MAXN]; 14 void push(int x) 15 { 16 stack[++top]=x; 17 } 18 int pop() 19 { 20 top--; 21 return stack[top+1]; 22 } 23 bool cmp() 24 { 25 if(top<=0) 26 return false; 27 else 28 return true; 29 } 30 }momo; 31 int now=0; 32 Edge edge[MAXN]; 33 int note[MAXN]; 34 int money[MAXN]; 35 int head[MAXN]; 36 void put(int vi,int vj) 37 { 38 edge[now].vi=vi; 39 edge[now].vj=vj; 40 edge[now].next=head[vi]; 41 head[vi]=now; 42 now++; 43 note[vj]++; 44 } 45 int main() 46 { 47 int n,m; 48 scanf("%d%d",&n,&m); 49 for(int i=1;i<=n;i++) 50 head[i]=-1; 51 for(int i=1;i<=n;i++) 52 money[i]=100; 53 for(int i=1;i<=m;i++) 54 { 55 int vi,vj; 56 scanf("%d%d",&vi,&vj); 57 put(vj,vi); 58 } 59 int ans=0; 60 for(int i=1;i<=n;i++) 61 if(note[i]==0) 62 { 63 momo.push(i); 64 note[i]--; 65 ans++; 66 } 67 while(momo.cmp()) 68 { 69 int num=momo.pop(); 70 for(int i=head[num];i!=-1;i=edge[i].next) 71 { 72 int j=edge[i].vj; 73 if(money[num]+1>money[j]) 74 money[j]=money[num]+1; 75 note[j]--; 76 if(note[j]==0) 77 { 78 momo.push(j); 79 note[j]--; 80 ans++; 81 } 82 } 83 } 84 int tot=0; 85 for(int i=1;i<=n;i++) 86 tot+=money[i]; 87 if(ans!=n) 88 printf("-1"); 89 else 90 printf("%d",tot); 91 return 0; 92 }