最小生成树
来源:互联网 发布:大白菜会计软件 编辑:程序博客网 时间:2024/06/07 02:10
以下介绍最小生成树的几个算法,Kruskal算法、Prim算法。
虽然网上有很多对于最小生成树的优质讲解,但是自己还是想写一下自己的理解与体会。
此处借用一下已有的经验(图解深深的吸引了我)。
Kruskal
先来讲一下kruskal算法,该算法的想法很简单,始终从未选取的边中选取最短的边并添加进去就好了。(此处未选取的边是指那些,边的任意一个顶点都没有被添加过),如有不明白的地方,请结合上面链接中的图解,进行推演并理解。
以下是模板:
/* *用边构图,也就是下面的Side结构体*/struct Side{ int from, to, wei; bool operator < (const struct Side s)const { return wei < s.wei; }}side[MAXE];int kruskal(int n, int m){ int Min = 0, node = n - 1; int root[MAXN]; for(int i = 0; i <= n; ++i) root[i] = i; sort(side, side + sideNum); for(int i = 0; node && i < sideNum; ++i) { if(Union(side[i], root)) { node--; Min += side[i].wei; } } return Min;}bool Union(const struct Side &s, int *root){ int p = Find(s.from, root); int q = Find(s.to, root); if(p != q) { root[p] = q; return true; } return false;}int Find(int p, int *root){ while(p != root[p]) { root[p] = root[root[p]]; p = root[p]; } return p;}
以上算法的贪心思想不难理解,然而对于贪心思想的正确性,此处运用了UnionFind数据结构。
正是UnionFind保证了选取边的时候,只考虑蓝边而忽略红边,从而可以得到生成树。
prim
prim算法与Dijstra算法相当类似,只是将原来的dist改为cost,用cost代表与该点相连的所有边中的最小权值。同样可以参照上面链接,进行推演理解。
以下是模板:
/* *此处采用的是邻接矩阵存储边的权值*/int prim(int N) { int res = 0; for(int i = 0; i < N; ++i) cost[i] = INF, vis[i] = false; cost[0] = 0; while(true) { int u = -1; for(int v = 0; v < N; ++v) { if(!vis[v] && (u == -1 || cost[v] < cost[u])) u = v; } if(u == -1) break; vis[u] = true; res += cost[u]; for(int v = 0; v < N; ++v) { cost[v] = min(cost[v], Map[u][v]); } } return res;}
这里推荐两个讲解次小生成树的链接,链接1,链接2。
次小生成树模板此处不给出,以后遇到题目再说吧。
0 0
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 树+最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树Kruskal
- kruskal 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树问题
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 两道面试题(英文版)
- 1062. Talent and Virtue (25)-PAT甲级
- 每日一题 No.20 a*b(位操作符)【正负数】
- nyoj-喷水装置(一)
- 华氏温度与摄氏温度转化(for循环)
- 最小生成树
- 蓝桥杯-未名湖边的烦恼-递归-java
- 回归
- c语言里缓冲区的理解
- POJ 2976 (最大化平均值)
- 逆序输出
- Huawei OJ-字符串通配符
- echarts中toolbox乱码问题
- glibc源码分析之进程启动(start.S)