标签:
题意:年终要给 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\n",ans);
56 else printf("-1\n");
57 }
58 return 0;
59 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4794925.html