给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(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(最小生成树)的更多相关文章

  1. HDU 4408 Minimum Spanning Tree 最小生成树计数

    Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. 【算法】关于图论中的最小生成树(Minimum Spanning Tree)详解

    本节纲要 什么是图(network) 什么是最小生成树 (minimum spanning tree) 最小生成树的算法 什么是图(network)? 这里的图当然不是我们日常说的图片或者地图.通常情 ...

  3. 【HDU 4408】Minimum Spanning Tree(最小生成树计数)

    Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...

  4. 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 ...

  5. 说说最小生成树(Minimum Spanning Tree)

    minimum spanning tree(MST) 最小生成树是连通无向带权图的一个子图,要求 能够连接图中的所有顶点.无环.路径的权重和为所有路径中最小的. graph-cut 对图的一个切割或者 ...

  6. 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集

    最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. DIV+CSS 星号*

    常常我们在DIV+CSS布局的时候会遇到2处使用星号“*”,一个为以星号*没有命名名称的CSS选择器:另外一个是在CSS选择器里以*开头的CSS属性单词样式-CSS星号-CSS *知识介绍.接下来DI ...

  2. Activity之多启动图标

    如果想要Activity有多个启动图标,只需要在manifest.xml文件中配置一下就可以了,直接上代码: 1 <application 2 android:allowBackup=" ...

  3. Oracle在中文环境下出现乱码解决办法

       zysong.ttf下载是一款oracle字体乱码解决工具,实质于缺乏中文字体包! 01情况的例子 02情况的例子 01.在开始安装的时候出现乱码 下载zysong.ttf,unzip 解压 一 ...

  4. 我的一个小作品 android App ---校园资讯助手

        软件主界面采用Fragment+ViewPager组成.在点开后将会自动对学校新闻页面使用URl类来抓取,然后对网页中的信息提取,使用WebView来loadData在主界面上面显示, 为了使 ...

  5. springmvc中实现quartz定时任务

    1.maven项目添加如下两个jar包,当然也需要相应的spring 的Jar <!-- Spring Quartz定时器 begin --> <dependency> < ...

  6. 网页中常用HTML字符实体

    摘要: 一些字符在 HTML 中拥有特殊的含义,比如小于号 () 用于定义 HTML 标签的开始.如果我们希望浏览器正确地显示这些字符,我们必须在 HTML 源码中插入字符实体. 字符实体有三部分:一 ...

  7. JAVA1种C++3种继承方式

    JAVA中只有一种public继承

  8. CDN 备胎技巧

    如果你使用 CDN 服务,建议准备一个备胎,万一 CDN 服务挂了,可以从自己的服务器上读取: <script src="http://cdn.staticfile.org/jquer ...

  9. JS 正则表达式中的特殊字符

    正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...

  10. css-css权威指南学习笔记2

    第二章 选择器 1.在font属性中,只有一种情况下可以使用/来分隔两个特定的关键字,即元素的字体大小/行高. 2.通过把两个类选择器链接在一起,可以选择同时包含这些类名的元素,类名的顺序不限. .w ...