Kruskal 算法求最小生成树
来源:互联网 发布:cf天赐软件视频 编辑:程序博客网 时间:2024/03/29 00:27
#include <iostream>#include <climits> /* for INT_MAX */#include <queue>#include <algorithm>using namespace std;#include <stdlib.h>/** 并查集. */typedef struct ufs_t { int *p; /** 树的双亲表示法*/ int size; /** 大小. */} ufs_t;/*** @brief 创建并查集.* @param[in] n 数组的容量* @return 并查集*/ufs_t* ufs_create(int n) { ufs_t *ufs = (ufs_t*)malloc(sizeof(ufs_t)); int i; ufs->p = (int*)malloc(n * sizeof(int)); for(i = 0; i < n; i++) ufs->p[i] = -1; return ufs;}/*** @brief 销毁并查集.* @param[in] ufs 并查集* @return 无*/void ufs_destroy(ufs_t *ufs) { free(ufs->p); free(ufs);}/*** @brief Find 操作,带路径压缩,递归版.* @param[in] s 并查集* @param[in] x 要查找的元素* @return 包含元素x 的树的根*/int ufs_find(ufs_t *ufs, int x) { if (ufs->p[x] < 0) return x; // 终止条件 return ufs->p[x] = ufs_find(ufs, ufs->p[x]); /* 回溯时的压缩路径*/}/*** @brief Union 操作,将y 并入到x 所在的集合.* @param[in] s 并查集* @param[in] x 一个元素* @param[in] y 另一个元素* @return 如果二者已经在同一集合,并失败,返回-1,否则返回0*/int ufs_union(ufs_t *ufs, int x, int y) { const int rx = ufs_find(ufs, x); const int ry = ufs_find(ufs, y); if(rx == ry) return -1; ufs->p[rx] += ufs->p[ry]; ufs->p[ry] = rx; return 0;}/*** @brief 获取元素所在的集合的大小* @param[in] ufs 并查集* @param[in] x 元素* @return 元素所在的集合的大小*/int ufs_set_size(ufs_t *ufs, int x) { const int rx = ufs_find(ufs, x); return -ufs->p[rx];}const int MAX_NV = 11; /* 顶点数最大值*/const int MAX_NE = 100; /* 最大边数*//** 边的权值类型. */typedef int graph_weight_t;/** 图的边. */struct edge_t{ int u; /** 顶点编号*/ int v; /** 顶点编号*/ graph_weight_t w; /** 权值*/ bool operator>(const edge_t &other) const { return w > other.w; }};edge_t edges[MAX_NE];/** @brief Kruskal 算法,堆+ 并查集.* @param[in] edges 边的数组* @param[in] n 边数,一定要大于或等于(顶点数-1)* @param[in] m 顶点数* @return MST 的边的权值之和*/graph_weight_t kruskal(const edge_t edges[], int n, int m) { graph_weight_t sum = 0; priority_queue<edge_t, vector<edge_t>, greater<edge_t> > q; ufs_t *s = ufs_create(MAX_NV); if (n < m - 1) return -1; /* 把所有边插入堆中*/ for (int i = 0; i < n; i++) { q.push(edges[i]); } for (int i = 0; i < n; i++) { /* 从堆中退出最小权值边*/ const edge_t e = q.top(); q.pop(); /* 取两顶点所在集合的根*/ const int u = ufs_find(s, e.u); const int v = ufs_find(s, e.v); if (u != v) { /* 不是同一集合,说明不连通*/ ufs_union(s, u, v); /* 合并,连通成一个分量*/ /* 输出生成树TE 的边,即此边加入TE */ cout << (char)('A' + e.u) << " - " << (char)('A' + e.v) << endl; sum += e.w; } } ufs_destroy(s); return sum;}int main() { int m, n; /* 读取顶点数,边数目*/ cin >> m >> n; /* 读取边信息*/ for (int i = 0; i < n; i++) { char chx, chy; int w; cin >> chx >> chy >> w; edges[i].u = chx - 'A'; edges[i].v = chy - 'A'; edges[i].w = w; } /* 求解最小生成树*/ cout << "Total : " << kruskal(edges, n, m) << endl; return 0;}/* test输入数据:7 11A B 7A D 5B C 8B D 9B E 7C E 5D E 15D F 6E F 8E G 9F G 11输出:A - DC - ED - FB - EA - BE - GTotal : 39*/
0 0
- Kruskal算法求最小生成树
- Kruskal 算法 求最小生成树
- 24.kruskal算法 求 最小生成树
- Kruskal算法(求最小生成树)
- Kruskal算法求最小生成树
- Kruskal 算法求最小生成树
- uva1395 Kruskal算法求最小生成树
- hdu1102 kruskal算法求最小生成树
- Kruskal算法求最小生成树
- Kruskal算法求MST(最小生成树)
- 求最小生成树Kruskal算法
- 水题 kruskal算法求最小生成树
- Kruskal算法求最小生成树
- 求最小生成树的Kruskal算法
- kruskal算法求最小生成树
- Kruskal算法求最小生成树 (最小堆优化)
- [算法第一轮复习] kruskal求最小生成树算法
- KrusKal求最小生成树
- SAT阅读中的常见文化词条
- LinuxShell知识总结
- 在android apk中调用@hide方法
- MFC全局函数AfxBeginThread 及其与CreateThread的区别
- gdcpc2015B题
- Kruskal 算法求最小生成树
- C/C++预处理运算符
- FragmentPagerAdapter 与FragmentStatePagerAdapter 的不同
- nginx + tomcat + redis问题记录
- Provisioning Profile
- OpenDaylight和ONOS控制器比较
- log4cplus的使用
- 关于SIGPIPE信号
- mysql数据库支持表情发送并保存到数据库方法