hdu3367 Pseudoforest
来源:互联网 发布:linux下修改机器名 编辑:程序博客网 时间:2024/05/19 09:49
题意是说求伪森林的边权之和最大。伪森林的定义是:每一个连通分量允许至多有一个环。
这题本质上和kruskal差不多,但是要注意:
因为要和最大,所以排序的时候从大到小。
排序后枚举每一条边,判断它的两个端点:
1.两个端点属于同一个集合。如果这个集合还没有环,那么就加上这条边并标记次集合有环
2.两个端点属于不同的集合。如果这两个集合至多只有一个集合有环的话,那么就可以加上这条边合并这两个集合,一定记得要修改合并后集合的环标志。
#include <iostream>#include<stdio.h>#include<algorithm>#define maxn 100010using namespace std;int n,m;typedef struct edge{ int u,v,w;} Edge;Edge e[maxn];int fa[maxn];int loop[maxn]; //当前并查集是否有环int cmp(const void *a,const void *b){ Edge* aa = (Edge*)a; Edge* bb = (Edge*)b; return bb->w - aa->w;}int find(int a){ return fa[a] == a?a:fa[a] = find(fa[a]);}int main(){ while(true) { scanf("%d %d",&n,&m); if(n+m == 0) break; for(int i = 0; i < n; i++) { fa[i] = i; loop[i] = 0; } for(int i = 0; i < m; i++) { scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w); } qsort(e,m,sizeof (Edge),cmp); int ans = 0; for(int i = 0 ; i < m; i++) { int u = e[i].u; int v = e[i].v; int w = e[i].w; int fa_u = find(u); int fa_v = find(v); if(fa_u == fa_v ) //属于同一个集合 { if(!loop[fa_u]) //如果这个集合还没有环 { loop[fa_u] = 1; ans+=w; } } else { if(loop[fa_u] + loop[fa_v] < 2) //两个连通分量至多一个环 { fa[fa_v] = fa_u; loop[fa_u] += loop[fa_v]; //改变环标记,父节点的环标记为两个集合的环数目的和 ans+=w; } } } printf("%d\n",ans); } return 0;}
0 0
- HDU3367--Pseudoforest
- HDU3367 Pseudoforest
- hdu3367 Pseudoforest
- HDU3367-Pseudoforest
- HDU3367 Pseudoforest 【并查集】+【贪心】
- hdu3367 Pseudoforest(最大生成树+伪森林)
- hdu3367
- HDU3367
- hdu3367
- Pseudoforest
- Pseudoforest
- hdu3367并查集
- hdu3367(最大生成树)
- hdu3367并查集+Kruskal
- hdu3367之并查集
- hdu3367(并查集+kruscal)
- hdu 3367 Pseudoforest
- HDU 3367 Pseudoforest
- mark
- 绝对路径与相对路径
- __devexit_p的功能
- iOS多线程的初步研究(九)-- dispatch源
- 利用java、js、html进行客户端工具开发的两个方法
- hdu3367 Pseudoforest
- PB控件属性之CommandButton和PictureButton
- 广告banner:手动滑动切换,自动切换,点击跳转,异步加载网络图片
- EL表达式截取字符串
- Javascript 模块化编程
- Android中的软引用(SoftRefrerence)和弱引用(WeakReference)
- 《烽烟OL》地图编辑器使用说明
- iOS开发- 文件共享(利用iTunes导入文件, 并且显示已有文件)
- c/c++:回调函数