MST (Kruskal Prim)
来源:互联网 发布:windows media 解码器 编辑:程序博客网 时间:2024/05/21 14:53
kruskal 需要对边集排序,所以只存储边的信息
#define E 100#define V 100#include<iostream>#include<algorithm>using namespace std;struct edge{int from=-1;int to=-1;int w=0;};edge edg[E];int vnum, edgenum;int cnt = 0;void add(int u, int v, int w,edge* e) {e[cnt].to = v;e[cnt].w = w;e[cnt].from = u;cnt++;}bool cmp(edge a, edge b) {return a.w < b.w;}void uni(int i, int j,int * fa) {int k = 1;if (i < j) {while (fa[k] != 0) { //起始结束值,初始值,循环条件if (k!=i&&fa[k] == fa[i]) fa[k] = fa[j];k++;}fa[i] = fa[j]; //传递 fa[j]}else {while (fa[k] != 0) {if (k!=j&&fa[k] == fa[j]) fa[k] = fa[i];k++;}fa[j] = fa[i]; //保存fa[i]的值,去寻找他的等价类元素}}edge* MST_kruskal(edge *e,edge* kru) {int set[V] = { 0 }, fa[V] = { 0 }; //注意默认值为0 or 为-1for (int i = 1; i <= vnum; i++) {set[i] = i;fa[i] = i;}sort(e, e + cnt, cmp);cnt = 0;for (int i = 0; e[i].w != 0; i++) {if (fa[e[i].from] != fa[e[i].to]) { //只与集合有关,与方向无关uni(e[i].from,e[i].to,fa);add(e[i].from, e[i].to, e[i].w, kru);}}return kru;}int main() {cin >> vnum>>edgenum;for(int k=0;k<edgenum;k++) {int i, j, w;cin >> i >> j >> w;add(i, j, w, edg);}edge res[V];MST_kruskal(edg, res);for (int i = 0; res[i].from!=-1; i++) { //i++后先判断条件,再执行,执行完并不判断条件,直接++cout << res[i].from << " " << res[i].to << " " << res[i].w << endl;}return 0;}Prim
从0号节点开始进入循环,循环n-1次(MST n-1条边),先初始化vis,lowcost,minc,并用0号节点赋值
vis保存节点是否被加入生成树中
lowcost维护的是(MST外)第i号节点到生成树的最小距离,只要把一个节点p加入生成树中,就使用cost[p][j]更新与p相邻接的所有树外j节点的lowcost值,不断更新,保证lowcost树外点到树的最小距离
下一次循环就选择离树最近的点,加入树并更新其他节点的lowcost值
#include<iostream>using namespace std;const int inf=0x3f3f3f3f;const int MAXN = 100;bool vis[MAXN];int lowcost[MAXN],vertexnum,edgenum,w[MAXN][MAXN];int MST_Prim(int cost[][MAXN], int n) { //weight matrix and vertex numberint res = 0;for (int i = 0; i < n; i++) {lowcost[i] = inf;vis[i] = false;}int minc = inf,p;for (int i = 0; i < n; i++) {lowcost[i] = cost[0][i];}vis[0] = true; //第一次循环的初始化for (int i = 1; i < n; i++) { //n个点,MST有n-1条边minc = inf, p = -1;for (int j = 0; j < n; j++) {if (!vis[j] && lowcost[j] < minc) {minc = lowcost[j];p = j;}}if (minc == inf) return -1;vis[p] = true;res = res + minc;for (int j = 0; j < n; j++) {if (!vis[j] && lowcost[j] > cost[p][j]) {lowcost[j] = cost[p][j];}}}return res;}int main() {cin >> vertexnum >> edgenum;for (int i = 0; i < vertexnum; i++)for (int j = 0; j < vertexnum; j++)w[i][j] = inf;while (edgenum--) {int i, j, k;cin >> i >> j >> k;w[i-1][j-1] = k;w[j-1][i-1] = k;}int ans = MST_Prim(w, vertexnum);cout << ans;return 0;}Prim算法以点为考虑对象,找到离树最近的树外点
Kruskal以边为考虑对象,找到连接树和树外的权值最小的边
Prim以点找边,所以有方向,如果无向图,则需要添加w[i][j]和w[j][i],否则找不到边
而Kruskal按权值排序找边,无关方向,若为有向图需考虑是否是from点树内,to树外
---------测试数据-----------
9
14
1 2 4
1 8 8
2 8 11
2 3 8
3 4 7
4 5 9
5 6 10
6 7 2
7 8 1
8 9 7
7 9 6
3 9 2
3 6 4
4 6 14
from CLRS Chap23
0 0
- poj2421【MST-prim+Kruskal】
- MST (Kruskal Prim)
- USACO Agri-Net, MST, Prim, Kruskal
- MST的Prim算法和Kruskal算法
- 最小生成树(MST):Prim / Kruskal
- 最小生成树(MST)—prim和kruskal算法
- 数据结构基础6.3:最小生成树MST(Prim、Kruskal)
- 算法整理:最小生成树(mst)-Prim+Kruskal
- 最小生成树MST(Prim/Kruskal模版)
- Kruskal【MST】
- kruskal 【MST】
- Prim【MST】
- Prim Kruskal
- Kruskal&&prim
- Kruskal&Prim
- Prim&Kruskal
- kruskal&&prim
- Prim算法求最小生成树MST以及和kruskal算法的对比
- 错误汇总
- 第十四周OJ项目C进制转换
- Java实现算法导论中Miller-Rabin随机性素数测试
- Eclipse Mars在线安装jd-eclipse反编译插件
- 按钮点击事件的实现方式---原生js
- MST (Kruskal Prim)
- Ajax
- birt 交叉表的设计
- Intent之对象传递(Serializable传递对象和对象集合)
- 一些SQL语句
- 2016年终总结
- 工程师成长之路:工作1-3年工程师如何突破瓶颈期
- 第十四周OJ项目D求矩阵
- LeetCode 74(Search a 2D Matrix)Java