原题链接: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 }
来源:https://www.cnblogs.com/tak-fate/p/5974813.html