最小生成树
来源:互联网 发布:绘画教程软件 编辑:程序博客网 时间:2024/06/06 01:16
最小生成树
概念:
一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。
简单来说:最小生成树就是在一个连通图(每个点都相连的无向图)中使得权值和最小的树,保证每个点都在里面。
最小生成树其实是最小权重生成树的简称。
最小生成树又叫“MST”。
应用:
例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。
求最小生成树的方法:
最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
prim算法的时间复杂度不依赖于排序算法,并且主要与点的个数有关,适用于密集图。
kruskal算法需要排序,但使用幷查集可节省判断时间,主要与边的条数有关,适用于稀疏图。
简单来说:Prim算法,适用于点少的图。Kruskal算法,适用于边少的图。
Prim算法
思想:
贪心思想:每次选取最小边。
算法描述:
(1)输入:一个加权连通图,其中顶点集合为V,边集合为E;
(2)初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
(3)重复下列操作,直到Vnew = V:
a.在集合E中选取权值最小的边< u, v >,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将< u, v >边加入集合Enew中;
(4)输出:使用集合Vnew和Enew来描述所得到的最小生成树。
图例描述:
时间复杂度:
顶点数v,边数e
邻接矩阵:O(v)
邻接表:O(elog2v)
代码:
#include<iostream>using namespace std;const int maxn=1000000;int n,k,tmp,ans,map[1001][1001],dis[maxn];bool flag[maxn];void prim(){ for(int i=1;i<=n;i++) dis[i]=maxn;//初始化 dis[1]=0; for(int i=1;i<=n;i++) { tmp=maxn; for(int j=1;j<=n;j++) if(!flag[j]&&tmp>dis[j]) { tmp=dis[j]; k=j; }//找出最小距离的节点 flag[k]=1;//把访问的节点做标记 for(int j=1;j<=n;j++) if(!flag[j]&&dis[j]>map[k][j]) dis[j]=map[k][j];//更新最短距离 }}int main(){ cin>>n; for(int i=1;i<=n;i++)//邻接矩阵储存权值 for(int j=1;j<=n;j++) cin>>map[i][j]; prim(); for(int i=1;i<=n;i++) ans+=dis[i]; cout<<ans; return 0;}
Kruskal算法
基本思路:
克鲁斯卡尔算法是在剩下的所有未选取的边中,找最小边,如果和已选取的边构成回路,则放弃,选取次小边。
#include<iostream>#include<algorithm>using namespace std;int n,e,fa[101],sum=0;struct node{ int o; int u; int t;}a[101];int find(int x){ if(father[x]!=x) father[x]=find(father[x]) return father[x];}int cmp(node a,node b) { return a.t < b.t;}void unionn(int x,int y){ int f1=find(x); int f2=find(y); if(f1!=f2)fa[f2]=f1;}int main(){ int k=0; cin>>n>>e; for(int i=1;i<=e;i++) cin>>a[i].o>>a[i].u>>a[i].t; for(int i=1;i<=n;i++) fa[i]=i; sort(a+1,a+1+e,cmp); for(int i=1;i<=e;i++) { if(find(a[i].o)!=find(a[i].u)) { unionn(a[i].o,a[i].u); sum=sum+a[i].t; k++; } if(k==n-1)break; } cout<<sum;}
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 树+最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树Kruskal
- kruskal 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树 MST
- 最小生成树问题
- 最小生成树
- 最小生成树
- 最小生成树
- 最小生成树
- Java异常体系
- LaunchImage 知识点
- Codevs 3269 混合背包(二进制优化)
- Class.forName()的作用与使用总结
- 基于thinkcmf制作长江文明馆框架总结
- 最小生成树
- 操作系统思考
- socket模块源码略看
- 一组常用的弹出窗口用法
- transition/animation与visibility/display
- java重载/重写(覆盖)/重构比较及其与C++差异
- 简论select()的接口设计与内核实现的得失(2)——The C10M Problem
- Java动态编程初探——Javassist
- C#中取得Web的当前目录