[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\n",sum);

86     }

87 }

88 int main()

89 {

90     solve();

91     return 0;

92 }

 

你可能感兴趣的:(HDU)