给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(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. SQL基础之select

    1.认识select select的主要语法如下,这个很重要因为只有记住了整体的结构才能应对任何情况.从中可以看到select的强大主要就是建立在where.group by.having.order ...

  2. web性能优化——浏览器相关

    简介 优化是一个持续的过程.所以尽可能的不要有人为的参与.所以能自动化的或者能从架构.框架级别解决的就最更高级别解决. 这样即能实现面对开发人员是透明的.不响应,又能确保所有资源都是被优化过的. 场景 ...

  3. 探究JVM——垃圾回收

    垃圾回收主要考虑三件事情:哪些内存需要回收?什么时候回收?如何回收? 一.哪些内存需要回收? 堆内存:对于JVM 来说,垃圾回收主要是针对堆内存中的对象实例. 方法区:垃圾收集行为在方法区是比较少出现 ...

  4. MATLAB如何定义函数

    自定义函数的途径:M文件函数(M file function)在线函数(Inline Function)匿名函数(Anonymous Function)1.M文件函数范例function c=myad ...

  5. Maven_Build_Resources

    功能:主要用于打包资源文件,默认情况下maven只打包src/main/resource下的资源,通过 1.设置build_resources 2.使用build-helper-maven-plugi ...

  6. 【CodeVS 5032】【省队集训2016 Day5 T1】Play with array

    一开始我用分块大法,分成$\sqrt{n}$块,每个块上维护一个Splay,然后balabala维护一下,时间复杂度是$O(n\sqrt{n}logn)$.后来对拍的时候发现比$O(n^2)$的暴力跑 ...

  7. jquery-通过js编写弹出窗口

    本文转载 本文主要是通过js动态控制div的高度,css控制浮动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...

  8. jsoup-提示java.net.SocketTimeoutException:Read timed out

    使用Jsoup.connect(url).get()连接某网站时偶尔会出现 java.net.SocketTimeoutException:Read timed out异常. 原因是默认的Socket ...

  9. 一起学HTML基础-利用CSS和JavaScript制作一个切换图片的网页

    由于个人原因,不详细写步骤 思路: 一.布局 二.制作图片区和按钮区的div及颜色.边框.背景属性等 三.用PS将四张图片剪切到同一个尺寸,重叠放置在图片切换区,透明度设置为0 四.点击对应按钮时,将 ...

  10. sublime text 3之快捷键操作

    1.安装插件 https://packagecontrol.io/installation 2.将 Tab缩进(制表符缩进) 改为 4个空格 打开Preferences -> Settings- ...