数据结构与算法分析–Minimum Spanning Tree(最小生成树)
- 给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree).
- 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Minimum Spanning Tree)。
- 1.prim版本的算法
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
- 1: #include<string.h>
- 2: #define INF 10000001
- 3: #define N 10001
- 4: int graph[N][N]; //夹着我们有N个点,这里存的是边(i,j)的花费(无向边)
- 5: //没有边时的花费就是INF
- 6: int cost[N]; //记录目前要把第i个点加入正确联盟所需要的花费
- 7: int last[N]; //记录第i个点是透过谁加入了正确联盟(等于是存在edge(last[i],i))
- 8: int choosed[N]; //记录是否已经加入正确联盟
- 9: int fin_cnt; //记录已经加入正确联盟点的个数
- 10: int total_cost; //记录总花费
- 11: void init(){
- 12: int i;
- 13: memset( choosed , 0 , sizeof(int));
- 14: //last = -1代表自己就是root,一开始所有点都是自己的parent
- 15: memset( last , -1 , sizeof(int));
- 16:
- 17: //以idx=0的点作为root开始看花费
- 18: cost[0]=0;
- 19: choosed[0]=1;
- 20: for( i = 1 ; i < N ; i++ ){
- 21: cost[i] = graph[0][i]; //如果有边cost就会是该条边,反之则会是INF
- 22: if( cost[i] != INF)
- 23: last[i] = 0;
- 24: }
- 25: fin_cnt=1; //一开始只有一个点在正确联盟
- 26: }
- 27:
- 28: void prim(){
- 29: int min; //用来存这一轮找到的最小花费
- 30: int min_idx; //用来存这一轮找到最小花费的是哪个点
- 31: int i;
- 32: while( fin_cnt < N ){ //如果小于N代表还没找完
- 33: min = INF; //初始化成INF,用来找最小值
- 34: min_idx=-1;
- 35: for( i = 1 ; i < N ; i++ ){ //跑过所有点,找最小值
- 36: if(choosed[i] == 0&&cost[i]<min){//已经在正确联盟里就不考虑
- 37: min_idx=i;
- 38: min=cost[i];
- 39: }
- 40: }
- 41: if( min_idx == -1 ) //如果没有找到就代表此图找不到spanning tree
- 42: break;
- 43:
- 44: choosed[min_idx]=1; //标记min_idx这个点进入了正确联盟
- 45: total_cost+=cost[min_idx]; //加上加入这个点的cost
- 46: fin_cnt++; //fin_cnt增加一,代表多了一个点已经确定
- 47:
- 48: //看看还有没有被选的点,有没有点能够透过min_idx这个点而更近的
- 49: for( i = 1 ; i < N ; i++){
- 50: if(choosed[min_idx] == 0 && graph[min_idx][i]<cost[i]){ //被选过的就跳过,有更近就更新
- 51: last[i] = min_idx;
- 52: cost[i] = graph[min_idx][i];
- 53: }
- 54: }
- 55: }
- 56: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
2.Kruskal版本的算法
Kruskal算法按照边的权值从小到大排序,再全部访问一遍,如果将该边加入当前生成树内不会产生圈,那么就把这条边加入到生成树中,逐步扩大生成树的大小。
接下来我们介绍如何判断是否产生重边。假设现在要把连接顶点u和顶点v的边e(u—>v,v—>u)加入到生成树中去,如果加入操作之前,u和v不在同一个连通分量内(两块不连接的图),那么加入e也不会产生圈。反之,如果u和v在同一个连通分量里,那么一定会产生圈。可以使用并查集搞笑的判断是否属于同一个连通分量。
- 1: #include<stdlib.h> //使用memset需要包含的头文件
- 2: #include<stdio.h>
- 3: #include<string.h>
- 4: #define maxn 10000
- 5: #define N 101
- 6: struct node{
- 7: int u,v,w;
- 8: }edges[maxn];
- 9: int total_cost;
- 10: int id[N];
- 11: int choosed[N];
- 12: int comp(const void*p,const void *q){//qsort需要重写它的排序规则
- 13: struct node a=*(struct node *)p;//类型强制转换
- 14: struct node b=*(struct node *)q;
- 15: return a.w-b.w;
- 16: }
- 17: int find_root(int idx){
- 18: if(id[idx]==-1)
- 19: return idx;
- 20: return id[idx]=find_root(id[idx]);
- 21: }
- 22:
- 23: void init(int n,int m){
- 24: int i;
- 25: memset(choosed,0,sizeof(choosed));
- 26: qsort(edges,n,sizeof(struct node),comp);//按边从小到大排序
- 27:
- 28: for(i=0;i<=m;i++)
- 29: id[i]=-1;
- 30: total_cost=0;
- 31: }
- 32: void kruskal(int n){
- 33: int i,x,y;
- 34: for(i=0;i<n;i++){
- 35: x=find_root(edges[i].u);
- 36: y=find_root(edges[i].v);
- 37: if(x!=y){//如果该条边添加后不构成回路
- 38: id[y]=x;
- 39: total_cost+=edges[i].w;//加上该条边的权重
- 40: choosed[edges[i].u]=1;
- 41: choosed[edges[i].v]=1;
- 42: }
- 43: }
- 44: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
数据结构与算法分析–Minimum Spanning Tree(最小生成树)的更多相关文章
- HDU 4408 Minimum Spanning Tree 最小生成树计数
Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解
本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情 ...
- 【HDU 4408】Minimum Spanning Tree(最小生成树计数)
Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- 说说最小生成树(Minimum Spanning Tree)
minimum spanning tree(MST) 最小生成树是连通无向带权图的一个子图,要求 能够连接图中的所有顶点.无环.路径的权重和为所有路径中最小的. graph-cut 对图的一个切割或者 ...
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST
E. Minimum spanning tree for each edge Connected undirected weighted graph without self-loops and ...
- CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值
E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...
随机推荐
- JQuery功能查询页
JQuery在前端开发中已经是常用的不能再常用的库了.最近的项目中使用到了JQuery,我第一次接触它的时候为了学习,把常用的操作指令用比较小的字体写在一页word上,打印出来贴在桌子上,用来让自己时 ...
- Euler Level 2
闲下来的时候就做点,慢慢的也终于到达Level 2了.
- LaTeX常用数学符号表示方法
转自:http://www.mohu.org/info/symbols/symbols.htm 常用数学符号的 LaTeX 表示方法 (以下内容主要摘自“一份不太简短的 LATEX2e 介绍”) 1. ...
- Ubuntu's Trash
1.Location Where is Trash? /home/userName/.local/share/Trash2.Under Trash Three files: ...
- 25 uname-用于显示系统信息
uname可显示电脑以及操作系统的相关信息. 语法 uname [-amnrsv][--help][--version] 参数说明: -a或--all 显示全部的信息. -m或--machine 显示 ...
- springMvc发布restFull风格的URL
package zpark.controller; import org.springframework.stereotype.Controller; import org.springframewo ...
- Activity has leaked window that was originally added -界面退出时未关闭对话框异常 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? -
退出Activity时弹出登录框,点击确定finish当前Activity,结果报了这个错,随后查找资料知道 原因: 是因为退出Activity时没有关闭弹出框,出现了这个错误 解决方法: 只需要在a ...
- Swift开发小技巧--识别选中照片中的二维码
识别选中照片中的二维码 点击相册按钮,打开用户相册 @IBAction func photoBtnClick(sender: AnyObject) { // 打开相册 // 1.判断是否能够打开相册 ...
- Elasticsearch静态集群配置
这两天需要将ELK中的单节点运行的ES扩展为双节点,查询了下集群配置,百度搜索结果还是一如既往的坑,基本都是各种转帖,以下记录配置静态集群的步骤: * * * <pre><code& ...
- 在浏览器中输入URL后执行的全部过程的个人总结
这个问题经常可以看到,今天我好好总结了下,是从网络模型的角度来分析问题的,主要涉及应用层:DNS,HTTP,传输层:TCP,网络层:IP和路由选择协议:RIP,OSPF(内部网关协议),BGP(外部网 ...