博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU - Pseudoforest
阅读量:5836 次
发布时间:2019-06-18

本文共 2772 字,大约阅读时间需要 9 分钟。

Description

In graph theory, a pseudoforest is an undirected graph in which every connected component has at most one cycle. The maximal pseudoforests of G are the pseudoforest subgraphs of G that are not contained within any larger pseudoforest of G. A pesudoforest is larger than another if and only if the total value of the edges is greater than another one’s. 
 

Input

The input consists of multiple test cases. The first line of each test case contains two integers, n(0 < n <= 10000), m(0 <= m <= 100000), which are the number of the vertexes and the number of the edges. The next m lines, each line consists of three integers, u, v, c, which means there is an edge with value c (0 < c <= 10000) between u and v. You can assume that there are no loop and no multiple edges. 
The last test case is followed by a line containing two zeros, which means the end of the input. 
 

Output

Output the sum of the value of the edges of the maximum pesudoforest. 
 

Sample Input

3 3 0 1 1 1 2 1 2 0 1 4 5 0 1 1 1 2 1 2 3 1 3 0 1 0 2 2 0 0
 

Sample Output

3 5
 
说说题目意思是必要的,毕竟小笼包都给我解释了好久,真是难以让人理解,题目意思就是合并出一个假森林出来,这个森林的环只能有一个,所谓环就是比如当0, 1, 2建立集合关系的时候
这个时候2已经链接到0了,也就是说0是可以到2的,这个时候如果系统在给你一组数据类似于2, 0的时候,继续合并,则0到1到2再到0,把它想成一圈,是不是就是一个环了,好了,理解这里应该就没有什么难度了,接下来的主要问题就是合并时的判断了,当两个节点同属于一个集合的时候,看看这个集合已经形成环了没有,如果形成了,就不能加入了,反之则可以,还有一种情况就是
两个节点分别属于不同的集合,因为合并的时候要考虑环的数量,所以当两个集合合并后新集合的环数量超过1也是不行的,还有一些问题我会在注释中注明:
 
#include
#include
#include
#include
#include
#include
#include
using namespace std; const int MX = 111111; int road[MX]; int sign[MX]; int rec[MX]; int n, m; struct Node { int a, b, c; }node[MX]; bool comp(const Node& n1, const Node& n2) { return n1.c > n2.c;//对价值进行排序,优先考虑放大的,贪心啦 } void ini() { for (int i = 0; i < n; i++) { road[i] = i; sign[i] = 0;//注意这个是用来标记环的数量的 rec[i] = 1;//注意这个是用来标记集合中的元素个数的,因为我采用了新的合并方法,就是把小集合合并到大集合,当然你也不用在意这种细节啦,你可以继续使用自己的合并方式 } } int FindRoot(int r) {//在使用路径压缩查找跟节点的时候我没有使用递归了,主要是不好进行各种标记 int root = r; while (road[root] != root) root = road[root]; int t1 = r; int t2 = r; while (road[t1] != root) { t2 = road[t1]; road[t1] = root; sign[t1] = sign[root]; t1 = t2; } return root; } int UnionRoot(int root1, int root2) {//基本的合并,一看就懂啦,看不懂就继续看- - if (rec[root1] >= rec[root2]) { road[root2] = root1; rec[root1]++; return root1; } else { road[root1] = root2; rec[root2]++; return root2; } } int main() { //freopen("input.txt", "r", stdin); while (scanf("%d%d", &n, &m), n || m) { ini(); for (int i = 0; i < m; i++) { scanf("%d%d%d", &node[i].a, &node[i].b, &node[i].c); } sort(node, node + m, comp);//基本的贪心思想 int ans = 0; for (int i = 0; i < m

转载于:https://www.cnblogs.com/steamedbun/p/5705918.html

你可能感兴趣的文章
阶乘素因子分解
查看>>
UVA-10212 The Last Non-zero Digit. 分解质因子+容斥定理
查看>>
80端口被占用时的终极解决方法
查看>>
使用 Strace 和 GDB 调试工具的乐趣
查看>>
android studio win7开发环境
查看>>
stddef.h(c标准库)
查看>>
NG-ZORRO 使用相关
查看>>
遗传算法
查看>>
Codeforces 1097G
查看>>
MySQL 5.7 innodb全文索引
查看>>
优秀Python学习资源收集汇总(强烈推荐)
查看>>
自然语言处理真实项目实战(20170822)
查看>>
枚举常见的七种用法
查看>>
更改 Sharepoint帐户的密码
查看>>
潜伏者(noip09年t1)解题报告 C++
查看>>
SPSS中,对数据进行转换
查看>>
自定义xib
查看>>
关于navigationbar背景色差问题与下方黑色边框解决办法
查看>>
picker组件,mode=date,苹果机年份从1开始
查看>>
新东方雅思词汇---6.2、重音在词根上,不在前后缀(名词除外)
查看>>