2016"百度之星"

  分析:首先,利用贪心可知,如果要所有人的分数和最高,需要把序号大的优先放在前面。其次,对于a的前面不能为b,那么只能a在b前面了,那么就建立一条从a到b的边,并且b的入度加1。然后就是拓扑排序了。要分数最高,则把哪些入度为0的点(他们不需要有哪些人一定要在他们前面,最自由)丢进优先队列,然后就可以实现把序号大的尽量放在前面而且满足题意了。

  具体见代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <vector>
 5 #include <queue>
 6 using namespace std;
 7 typedef long long ll;
 8 
 9 vector<int> G[100000+5];
10 int in[100000+5],val[100000+5];
11 int n,m;
12 void solve()
13 {
14     int sit=1;
15     priority_queue<int> Q;
16     for(int i=1;i<=n;i++) if(!in[i]) Q.push(i);
17     while(!Q.empty())
18     {
19         int x=Q.top();Q.pop();
20         val[sit++]=x;
21         for(int i=0;i<G[x].size();i++)
22         {
23             int v = G[x][i];
24             in[v]--;
25             if(!in[v]) Q.push(v);
26         }
27     }
28 }
29 int main()
30 {
31     int T;
32     scanf("%d",&T);
33     while(T--)
34     {
35         scanf("%d%d",&n,&m);
36         for(int i=1;i<=n;i++) G[i] .clear();
37         memset(in,0,sizeof(in));
38         memset(val,0,sizeof(val));
39         while(m--)
40         {
41             int u,v;
42             scanf("%d%d",&u,&v);
43             G[u].push_back(v);
44             in[v]++;
45         }
46         solve();
47         int minn=100000+5;
48         ll ans=0;
49         for(int i=1;i<=n;i++)
50         {
51             minn=min(minn,val[i]);
52             ans+=(ll)minn;
53         }
54         printf("%I64d
",ans);
55     }
56     return 0;
57 }

  

原文地址:https://www.cnblogs.com/zzyDS/p/5516652.html