POJ 2377 最大生成树
来源:互联网 发布:ansys14.5软件下载 编辑:程序博客网 时间:2024/05/22 22:00
问题描述: n个顶点,m条边,每条边有一个cost。 从m条边中选择若干条边使得n个顶点构成一颗树,要求cost的总和花费最大(最小)。
解决方案: kruskar算法生成最小生成树。关键点在于判断边的加入是否会引入环,环的检查使用并查集来实现,复杂度是O(lgN)。
算法的思想是贪心, 需要将输入的边按照cost从小到大排序,边的选择就是按照cost进行选择的。
#include<iostream>#include<algorithm>#include<fstream>using namespace std;//#define DEBUGstruct edge{int u;int v;int w;};bool cmp(const edge &a, const edge &b){return a.w > b.w;}static struct edge edges[20000];static int p[1001];static int num[1001];int findset(int x) /* 压缩路径 */{if (x != p[x])p[x] = findset(p[x]);return p[x];}int unionset(int s1, int s2) /* 按照数量合并 */{if (s1 == s2)return -1;if (num[s1] > num[s2]){p[s2] = s1; num[s2] = 0;}else{p[s1] = s2; num[s1] = 0;}return 0;}int main(){#ifdef DEBUGfstream cin("G:\\book\\algorithms\\acm\\Debug\\dat.txt");#endifint n, m;cin >> n >> m;int i;for (i = 0; i < m; i++){cin >> edges[i].u >> edges[i].v >> edges[i].w;}sort(edges, edges + m, cmp);/* 降序排列 贪心*/for (i = 1; i <= n; i++){p[i] = i;num[i] = 1;}int cost = 0;int trees = n;for (i = 0; i < m; i++){int pu, pv;pu = findset(edges[i].u);pv = findset(edges[i].v);if (pv != pu) /* the edge connect different trees */{unionset(pv,pu);cost += edges[i].w;trees--;}}if (trees > 1)cout << -1 << "\n";else cout << cost << "\n"; return 0;}
使用最小生成树算法,理论分析见算法导论的23.2小节。
基本的算法思想是贪心算法。对输入的边按照权重进行排序后依次处理,根据排序的方式决定是最大生成树还是最小生成树。
成树的过程中防止生成环, 采用并查集的方式进行检测。可以看出使用并查集后算法的过程就很简单了。复杂度是和边的数目有关的,
是否能够成树,即是否最终能够得到一个联通图,采用变量进行检测即可。
Kruskal算法对边进行操作,初始状态是n棵树构成的森林,通过边将各个树联通,构成一个无环的联通图
- 【最大生成树】POJ 2377
- POJ 2377 最大生成树
- poj 2377 最大生成树
- POJ 2377 最大生成树
- POJ 2377(最大生成树)
- POJ 2377 最大生成树 prim实现
- POJ 2377 Bad Cowtractors 最大生成树
- POJ 2377 Bad Cowtractors(最大生成树)
- POJ 2377 Bad Cowtractors【最大生成树】
- poj 2377最大生成树 Kruskal
- POJ 2377 Bad Cowtractors 【最大生成树】
- POJ 2377 (最大生成树 Kruskal)
- POJ 2377 - Bad Cowtractors(最大生成树)
- POJ-2377--Bad Cowtractors---最大生成树
- poj 2377 最大生成树 最小生成树的变形
- poj 3723 最大生成树
- poj 2377 Bad Cowtractors(最大生成树)
- POJ - 2377 Bad Cowtractors (最大生成树,Kruskal)
- Struts2的Convention插件的好处与使用
- 分别使用递归和非递归实现二分查找算法
- android的窗口机制分析------事件处理
- 递归练习
- hdu 1025 Constructing Roads In JGShining's Kingdom(最长上升序列n*logn算法)
- POJ 2377 最大生成树
- ffmpeg的使用
- POJ3630-静态字典树
- Tree.Panel各项属性
- HDU 2227 Find the nondecreasing subsequences (线段树)
- U盘启动安装Ubuntu 13.04
- Windows文件读写速度
- OpenCV 2 学习笔记(15): 绘制图像直方图
- 在Eclipse中的SVN提交时错误:Transaction is out of date