逆拓扑排序 HDU2647Reward

这个题如果用邻接矩阵的话,由于n比较大,会超内存,所以选用邻接表的形式。还有就是这个题有那个等级的问题,一级比一级的福利高,所以不能直接拓扑排序,而是反过来,计算出度,找出度为0的顶点,然后更新出度数组,等级更新的时候要判断是否比原来的等级大,具体看代码

 1 /*************************************************************************
 2     > File Name: hdu_1647.cpp
 3     > Author: 
 4     > Mail: 
 5     > Created Time: 2015年03月28日 星期六 16时18分47秒
 6  ************************************************************************/
 7 
 8 #include<iostream>
 9 #include <cstdio>
10 #include <cstring>
11 #include <stdlib.h>
12 using namespace std;
13 const int N = 10004;
14 int OutDegree[N];//出度
15 struct Node{//邻接表
16     int start;
17     struct Node *next;
18 };
19 Node *node[N];
20 int n, m, ans;
21 int level[N];//等级
22 bool Topo()
23 {
24     int cnt = 0;//统计个数
25     for (int i = 1; i <= n; i++)
26     {
27         for (int j = 1; j <= n; j++)
28         {
29             if (OutDegree[j] == 0)//找到出度为0的顶点
30             {
31                 cnt++;
32                 OutDegree[j]--;
33                 ans += level[j] + 888;
34                 Node *tmp = node[j]->next;
35                 while (tmp != NULL)//将所有跟他有关的边去掉
36                 {
37                     OutDegree[tmp->start]--;
38                     level[tmp->start] = max(level[tmp->start], level[j] + 1);//比较等级之间的关系,取较大的那个
39                     tmp = tmp->next;
40                 }
41             }
42         }
43     }
44     if (cnt == n)//判断是否存在环
45         return true;
46     return false;
47 }
48 int main()
49 {
50     while (~scanf("%d %d", &n, &m))
51     {
52         ans = 0;
53         int a, b;
54         memset(level, 0, sizeof(level));
55         memset(OutDegree, 0, sizeof(OutDegree));
56         for (int i = 1; i <= n; i++)//初始化
57         {
58             node[i] = (Node *)malloc(sizeof(Node));
59             node[i]->start = 0;
60             node[i]->next = NULL;
61         }
62 
63         for (int i = 0; i < m; i++)
64         {
65             scanf("%d %d", &a, &b);
66             OutDegree[a]++;
67             Node *tmp = node[b];
68             while (tmp->next != NULL)
69                 tmp = tmp->next;
70             Node *new_node = (Node *)malloc(sizeof(Node));
71             new_node->start = a;
72             new_node->next = NULL;
73             tmp->next = new_node;
74         }
75         if (Topo())
76             printf("%d\n", ans);
77         else
78             puts("-1");
79         for (int i = 1; i <= n; i++)
80             free(node[i]);
81     }
82 
83     return 0;
84 }
View Code

 

转载于:https://www.cnblogs.com/Howe-Young/p/4374601.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值