(拓扑排序)HDU - 2647 Reward

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647


题意:

一场比赛,现在已经有了结果,主办方要给选手分配奖励,判断是否能够分配,如果不能就输出-1,不能的话就输出主办方最小需要准备的奖金总数。

每个选手最低给888元。


 

分析:

拓扑排序入门题吧。。

我选择邻接表。

把边倒着连,就能从最小开始,然后在进行队列的时候,然后进行一次拓扑排序即可,这里不同的奖金额度只需要用一个结构体里存一个level属性就可以了,一开始为0,后面push的+1就行了。

每次pop加888+level。

注意的地方就是:这题需要输出-1,一开始我只判断了有双向边,其实还应该判断是否成环,只要加个变量记录点访问的个数就行了。


 

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #include<set>
  7 #include<vector>
  8 #include<queue>
  9 #include<map>
 10 #include<list>
 11 #include<bitset>
 12 #include<string>
 13 #include<cctype>
 14 #include<cstdlib>
 15 #include<sstream>
 16 
 17 using namespace std;
 18 
 19 typedef long long ll;
 20 typedef unsigned long long ull;
 21 #define inf (0x3f3f3f3f)
 22 #define lnf (0x3f3f3f3f3f3f3f3f)
 23 #define eps (1e-8)
 24 int sgn(double a) {
 25     return a < -eps ? -1 : a < eps ? 0 : 1;
 26 }
 27 
 28 const int maxn=10010;
 29 struct Node {
 30     int p,le;
 31 };
 32 
 33 ll ans;
 34 int pn;
 35 int m,n;
 36 
 37 vector<int> edge[maxn];
 38 int indu[maxn];
 39 
 40 
 41 
 42 void toposort() {
 43     queue<Node> q;
 44 
 45     for(int i=1; i<=n; i++) {
 46         if(indu[i]==0) {
 47             q.push(Node{i,0});
 48             indu[i]--;
 49         }
 50     }
 51 
 52     while(!q.empty()) {
 53         Node s = q.front();
 54         pn--;
 55         q.pop();
 56         ans+=s.le+888;
 57         for(int i=0; i<edge[s.p].size(); i++) {
 58             indu[edge[s.p][i]]--;
 59             if(indu[edge[s.p][i]]==0) {
 60                 q.push(Node{edge[s.p][i],s.le+1});
 61             }
 62         }
 63     }
 64 }
 65 
 66 
 67 void solve() {
 68 
 69     while(~scanf("%d%d",&n,&m)) {
 70         pn=n;
 71         for(int i=1; i<=n; i++) {
 72             edge[i].clear();
 73         }
 74         memset(indu,0,sizeof(indu));
 75         ans=0;
 76         int u,v;
 77         bool flag=true;
 78         for(int i=0; i<m; i++) {
 79             scanf("%d%d",&v,&u);
 80             for(int j=0; j<edge[v].size()&&flag; j++) {
 81                 if(edge[v][j]==u) {
 82                     flag=false;
 83                 }
 84             }
 85             bool have=false;
 86             for(int j=0; j<edge[u].size()&&flag&&!have; j++) {
 87                 if(edge[u][j]==v) {
 88                     have=true;
 89                 }
 90             }
 91             if(!have) {
 92                 indu[v]++;
 93                 edge[u].push_back(v);
 94             }
 95         }
 96         if(flag) {
 97             toposort();
 98             if(pn==0) {
 99                 printf("%lld\n",ans);
100             } else {
101                 puts("-1");
102             }
103 
104         } else {
105             puts("-1");
106         }
107     }
108 }
109 
110 
111 
112 int main() {
113 
114 #ifndef ONLINE_JUDGE
115     freopen("in.txt", "r", stdin);
116     //freopen("out.txt", "w", stdout);
117 #endif
118     //iostream::sync_with_stdio(false);
119     solve();
120     return 0;
121 }

 

posted @ 2016-10-18 20:36  tak_fate  阅读(283)  评论(0编辑  收藏  举报