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

本文共 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

你可能感兴趣的文章
linux之iptable案例
查看>>
C#制表符过滤处理方法
查看>>
注解的原理
查看>>
计划在CSDN学院推出系列视频课程《源码分析教程5部曲》
查看>>
live555学习之RTSP连接建立以及请求消息处理过程
查看>>
李礼辉:区分数字货币与数字代币,数字货币代表货币的未来
查看>>
马云谈NASA:投资让人更有创造力的技术
查看>>
二维码扫描&amp;集合排序
查看>>
win8.1中输入中文显示问号的解决办法
查看>>
自己常用的字符实体
查看>>
我在Mesos上运行Docker容器的经验
查看>>
5分钟用Jitpack发布开源库
查看>>
ASP.NET MVC的Model元数据与Model模板:模板的获取与执行策略
查看>>
基于机器学习的web异常检测
查看>>
中国人工智能学会通讯——Bots:下一站王者 1.1 引言
查看>>
攻击者利用BlackEnergy销毁磁盘文件
查看>>
技术干货|如何在微服务架构下构建高效的运维管理平台?
查看>>
如何最大化自动补丁管理工具的作用?
查看>>
人工智能创新有望解决大数据难题
查看>>
阿里云E-MapReduce快速入门之准备工作
查看>>