hdu 3367 最大伪森林(kruskal)
2015-07-20 15:32
423 查看
最大伪森林:原图的一个子图,在子图的各个连通分量中至多有一个环,且各边权和最大。
方法:kruskal,只是排序按边权从大到小,合并的时候注意判断是否构成多个环。
方法:kruskal,只是排序按边权从大到小,合并的时候注意判断是否构成多个环。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int N = 10000; const int M = 100000; int f ; bool cycle ; struct Edge { int u, v, w; bool operator < ( const Edge & o ) const { return w > o.w; } } edge[M]; int findf( int x ) { if ( f[x] != x ) f[x] = findf(f[x]); return f[x]; } int main () { int n, m; while ( scanf("%d%d", &n, &m) != EOF ) { if ( n == 0 && m == 0 ) break; for ( int i = 0; i < m; i++ ) { scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w); } for ( int i = 0; i < n; i++ ) { f[i] = i; } sort( edge, edge + m ); memset( cycle, 0, sizeof(cycle) ); int sum = 0; for ( int i = 0; i < m; i++ ) { int u = edge[i].u, v = edge[i].v, w = edge[i].w; u = findf(u), v = findf(v); if ( u == v ) { if ( !cycle[u] ) { sum += w; cycle[u] = 1; } } else { if ( cycle[u] && cycle[v] ) { continue; } sum += w; f[u] = v; if ( cycle[u] || cycle[v] ) { cycle[v] = 1; } } } printf("%d\n", sum); } return 0; }
相关文章推荐
- 极客编程小挑战#26:实现日期级联下拉选择框
- 写哪儿指哪儿——值传递
- MSSQL - 用GUID值来完成数据表行标识
- openssl 自签发证书及ssl 原理简介(一)
- ACM_Bellman-ford算法
- ArcGis转换OSM数据及其数据裁剪
- LeetCode—Count Primes
- IOS:MD5加密
- php 数组转xml
- zoj 1586 QS Network
- 欢迎使用CSDN-markdown编辑器
- getApn has exception: No permission to write APN settings
- 让多个Fragment切换不实例化
- zoj 1586 QS Network
- 职场中的十大低级错误
- hdu 1814 Peaceful Commission(2-sat)
- 通过浏览器直接打开Android应用程序
- 【CF】222 Div.1 B Preparing for the Contest
- [转]关于GET和POST的区别
- Java学习从入门到精通Java Learning Path