第二篇博客,看来以后要每天一篇的样子呢!
2016-07-15 16:55
274 查看
第二篇博客,看来以后要每天一篇的样子呢!
最小生成树
今天我们学习了最小生成树还有莫名其妙的次小生成树!两个新的算法:Prim算法和Kruskal算法。
1.Prim算法
原理:
设G=(V,E)是一个有向连通图,U是顶点集V的一个子集
如果:
1、边(u,v)
, u∈U且v∈(V-U),一个顶点在U中、另一个端点不在U中
2、(u,v)是满足条件1最小权值的边,那么一定存在G的一棵最小生成树包含(u,v)
操作:
•初始令U={v0}(v0
ÎV), TE={}
•在所有uÎU,
vÎV-U的边(u,v)ÎE中,找一条权最小的边(u0,v0)
•将(u0,v0)并入集合TE,同时v0并入U
•重复上述操作直至U等于V
•T=(V, {TE})为N的最小生成树
•如何表示集合U与集合V-U?
可以使用vis[]数组
vis[i]==1
表示在集合U中;
vis[i]==0
表示在集合V-U中;
•如何来找符合条件边?
辅助数组:minn[]
minn[i]用于记录节点i到达点集U的最短权值
算法框架:
1、任选一个点加入到集合U中;
2、选出N-1条边:
for(i=1;i<=n-1;i++){
1)找到最小的边的u-v;
2)将v加入到集合U中;
3)将未加入U集合的点的minn值更新;
}
2.kruskal算法:
①初始G(V,{}),即包含所有节点,边为空
②将原图中所有的边按权值从小到大排序
③从权值最小的边开始,如果这条边连接的两个节点于图G中不在同一个连通分量中,则添加这条边到图G中
④重复3,直至图G中所有的节点都在同一个连通分量中
注:用并查集判断是否在同一个联通分量中!
算法框架:
1.初始化并查集。father[x]=x。
2.tot=0
3.将所有边用快排从小到大排序。
4.计数器 k=0;
5.for (i=1; i<=M; i++)
//循环所有已从小到大排序的边
if
这是一条u,v不属于同一集合的边(u,v)(因为已经排序,所以必为最小),
{
①合并u,v所在的集合,相当于把边(u,v)加入最小生成树。
②tot=tot+W(u,v)
③k++
④如果k=n-1,说明最小生成树已经生成,则break;
}
6.结束,tot即为最小生成树的总权值之和。
次小生成树
证明有一大堆在此不做赘述。
求次小生成树的过程:
1、找到最小生成树;
2、找到所相差的边;(枚举)
3、替换;(如果非最小生成树中的边为(u,v),则替换最小生成树u->v的路径上最长的那条)
u->v路径上的最长边:
prim是每次增加一个结点s,
在此需要保存节点和其父节点,
则最大权值,要么是新加入的边,要么是父节点到起始点的采用DP算出来的距离。
嗯。。。次小生成树有点点麻烦,需要多多练习。
相关文章推荐
- POJ 2796 Feel Good(并查集)
- Java多线程用法
- 二叉查找树、B-树、B+树、B*树
- uwsgi安装过程中遇到的问题
- oracle database link使用说明
- 利用GPU加速的软件
- 关于正则表达式
- Observer观察者模式
- 快捷的办法找到并删除 Xcode 工程中没用到的图片
- android加载网络图片,并下载
- java string类型转换boolean类型
- eclipse 创建maven项目设置默认jdk版本
- ubuntu 下安装lua语言
- 【Leetcode206】 Reverse Linked List
- Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn(暴力)
- cuda 安装方法
- oracle数据库客户端无法分发数据库连接
- Tomcat log4j配置
- mysql 5.6 binlog组提交1
- Nginx之Keepalived高可用