hdu2647 拓扑序

题意:年终要给 n 个员工发奖金,每个人的起始金额是888,有些人觉得自己做的比另一个人好所以应该多得一些钱,问最少需要花多少钱,如果不能满足所有员工的要求,输出 -1

拓扑排序,从奖金少的向奖金多的建边,这样从奖金少的开始可以定 888 。对所有最开始入度为 0 的点开始,全发 888 ,由于加入队列的点的奖金数额其实是从小到大的,所以当某个点入度减为 0 时,就直接用这次用来更新的点的奖金+1 作为新一个点的奖金就行。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn=1e4+5;
 6 const int maxm=2e4+5;
 7 
 8 int ans,n;
 9 int id[maxn],num[maxn];
10 int head[maxn],point[maxm],nxt[maxm],size;
11 
12 void add(int a,int b){
13     point[size]=b;
14     nxt[size]=head[a];
15     head[a]=size++;
16     id[b]++;
17 }
18 
19 bool topo(){
20     ans=0;
21     queue<int>q;
22     for(int i=1;i<=n;++i)if(!id[i]){
23         q.push(i);
24         num[i]=888;
25     }
26     int cnt=0;
27     while(!q.empty()){
28         int u=q.front();q.pop();
29         ans+=num[u];
30         cnt++;
31         for(int i=head[u];~i;i=nxt[i]){
32             int j=point[i];
33             id[j]--;
34             if(!id[j]){
35                 num[j]=num[u]+1;
36                 q.push(j);
37             }
38         }
39     }
40     if(cnt==n)return 1;
41     return 0;
42 }
43 
44 int main(){
45     int m;
46     while(scanf("%d%d",&n,&m)!=EOF){
47         memset(head,-1,sizeof(head));
48         size=0;
49         memset(id,0,sizeof(id));
50         while(m--){
51             int a,b;
52             scanf("%d%d",&a,&b);
53             add(b,a);
54         }
55         if(topo())printf("%d
",ans);
56         else printf("-1
");
57     }
58     return 0;
59 }
View Code
原文地址:https://www.cnblogs.com/cenariusxz/p/4794925.html