原题链接: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 ",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 }