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<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<string>
#include<iostream>
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; i++) {
int root1 = FindRoot(node[i].a);
int root2 = FindRoot(node[i].b);
if (root1 == root2 && sign[root1] == 0) {//当两个节点同属于一个集合的时候,看看这个集合已经形成环了没有,如果形成了,就不能加入了,反之则可以
ans += node[i].c;
sign[root1] = 1;
} else {
if (sign[root1] != 1 || sign[root2] != 1) {//两个节点分别属于不同的集合,因为合并的时候要考虑环的数量,所以当两个集合合并后新集合的环数量超过1也是不行的
ans += node[i].c;
int r = UnionRoot(root1, root2);
if (sign[root1] == 1 || sign[root2] == 1) {
sign[r] = 1;
}
}
}
}
printf("%d\n", ans);
}
return 0;
}
 
 
 
 
 

HDU - Pseudoforest的更多相关文章

  1. hdu 3367(Pseudoforest ) (最大生成树)

    Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  2. hdu 3367 Pseudoforest (最大生成树 最多存在一个环)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3367 Pseudoforest Time Limit: 10000/5000 MS (Java/Oth ...

  3. hdu 3367 Pseudoforest(最大生成树)

    Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  4. hdu 3367 Pseudoforest

    Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  5. hdu 3367 Pseudoforest (最小生成树)

    Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  6. HDU 3367 Pseudoforest(Kruskal)

    Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  7. hdu 3367 Pseudoforest(并查集)

    题意:有一种叫作Pseudoforest的结构,表示在无向图上,每一个块中选取至多包含一个环的边的集合,又称“伪森林”.问这个集合中的所有边权之和最大是多少? 分析:如果没有环,那么构造的就是最大生成 ...

  8. hdu 3367 Pseudoforest 最大生成树★

    #include <cstdio> #include <cstring> #include <vector> #include <algorithm> ...

  9. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

随机推荐

  1. Android4.4 以太网和DHCP启动过程介绍

    转自:http://blog.csdn.net/wlwl0071986/article/details/51451843 Android4.4已经加入了以太网的支持.现在对以太网的初始化流程.网络策略 ...

  2. **代码审查:Phabricator命令行工具Arcanist的基本用法

    Phabricator入门手册 http://www.oschina.net/question/191440_125562 Pharicator是FB的代码审查工具,现在我所在的团队也使用它来进行代码 ...

  3. Eclipse 快捷键 转换为Netbeans 快捷键

    一直使用netbeans IDE开发,习惯了netbeans的快捷键,最近要开发个app就选择了H5. 接着使用了HBuilder (基于Eclipse开发) 总体来讲这个IDE还可以,不管是代码提示 ...

  4. 【网络资料】如何优雅地使用Sublime Text3

    如何优雅地使用Sublime Text3 Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩展机制,用她来写代码,绝对是一种享受.相 ...

  5. [LeetCode] Word Break II (TLE)

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  6. PHP检测终端设备是平板、手机还是电脑

    <?php $ua = $_SERVER['HTTP_USER_AGENT']; function userAgent($ua){ $iphone = strstr(strtolower($ua ...

  7. hdu 5294 最短路+最大流 ***

    处理处最短路径图,这个比较巧妙 链接:点我

  8. Win7下用IIS发布网站

    安装IIS控制面板->程序->程序和功能, 点击左侧的“打开或关闭Windows功能”把这几项都勾上吧,虽然有些不是必须的,多勾无碍. 进入IIS管理器控制面板-> 系统和安全-&g ...

  9. 在Salesforce中以PDF的格式显示对应的页面

    在Salesforce中可以简单设置page的属性让页面以pdf的方式显示内容, 当然了我们的page内容可以用Html的方式编写 设置方式为:renderAs="pdf" 请看如 ...

  10. js日期格式化

    <html> <head> <script> function test(){ //Js获取当前日期时间及其它操作 var myDate = new Date(); ...