[HDU] 2647 Reward(拓扑排序)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2647

拓扑排序问题,反向建图,则最后入度为0的点初始金钱为888,以后每次删边入度为0的点金钱比上次+1即可。若存在环,则不可能出现,输出-1。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<math.h>
 6 #include<stdbool.h>
 7 #include<time.h>
 8 #include<stdlib.h>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<queue>
13 #include<vector>
14 using namespace std;
15 #define clr(x,y)    memset(x,y,sizeof(x))
16 #define sqr(x)      ((x)*(x))
17 #define rep(i,a,b)  for(int i=(a);i<=(b);i++)
18 #define LL          long long
19 #define INF         0x3f3f3f3f
20 #define A           first
21 #define B           second
22 const int N=10000+131;
23 const int M=888;
24 int n,m,cnt,sum,num,d[N],head[N],path[N];
25 
26 struct node
27 {
28     int u,v;
29     int next;
30 } edge[2*N];
31 
32 void init()
33 {
34     clr(d,0);
35     clr(head,-1);
36     cnt=0;
37     sum=0;
38     num=-1;
39 }
40 
41 void add(int u,int v)
42 {
43     edge[cnt].v=v;
44     edge[cnt].next=head[u];
45     head[u]=cnt++;
46 }
47 
48 void solve()
49 {
50     int u,i,f,p,x,y,res;
51     while(~scanf("%d%d",&n,&m)) {
52             init();
53             while(m--) {
54                 scanf("%d%d",&x,&y);
55                 add(y,x);
56                 d[x]++;
57             }
58             
59             for(int i=0;i<n;i++) {
60                 num++;
61                 f=0;p=0;res=0;
62                 for(int j=1;j<=n;j++) {
63                     if(!d[j]) {
64                         u=j;
65                         d[j]--;
66                         sum+=M+num;
67                         f=1;
68                         path[res++]=j;
69                     }
70                     if(d[j]>0) p=1;
71                 }
72                 
73                 if(!f && p){  //有入度大于0的点,但不存在入度为0的点。即存在环
74                     sum=-1;
75                     break;
76                 }
77                 
78                 for(int k=0;k<res;k++) {
79                     u=path[k];
80                     for(int j=head[u];j!=-1;j=edge[j].next) {
81                         d[edge[j].v]--;
82                     }
83                 }
84             }
85             printf("%d
",sum);
86     }
87 }
88 int main()
89 {
90     solve();
91     return 0;
92 }
原文地址:https://www.cnblogs.com/sxiszero/p/4362933.html