给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(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. <实训|第十天>从底层解释一下U盘内存为什么变小的原因附数据恢复的基本原理

    [root@localhost~]#序言 我们平时不论是买一个U盘硬盘,或者自己在电脑上创建一个分区,大小总是比我们创建的要小一点,有些人会说,这个正常啊,是因为厂家规定的1M=1000k,真正的是1 ...

  2. 项目分享二:APP 小红点中数字的处理

    小红点,是 APP 中最常见的一个功能,我们先来看一下面的案例,下图中,待评价的商品有 2 个,点击“评价晒单”按钮进行评价后,那么待评价数量应该变成 1,那么这个功能是如何去实现的呢? 一般来说,实 ...

  3. Web Api 2 接口API文档美化

    使用用第三方提供的swgger ui 帮助提高 web api 接口列表的阅读性,并且可以在页面中测试服务接口. 运行程序如下: 注意:在IE中必须输入红色部分. 并且可以对方法进行测试. 在开发we ...

  4. [HDOJ5439]Aggregated Counting(乱搞)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5439 题意:按规则构造一个数列a a(1)=1 a(2)=2 a(2)=2 -------> 写两个 ...

  5. 跨浏览器事件EventUtil

    <div style="width: 150px; height: 150px; padding: 25px; border:1px solid blue; " id=&qu ...

  6. Android下的数据储存方式( 二)

    在上一篇文章中我们介绍了SharedPreferences的使用方法. 今天我们继续介绍另一种储存数据的方式:使用内部储存和外部储存 每一个Android设备都拥有两个数据储存区域:外部储存和外部储存 ...

  7. 切割haproxy的日志

    日志的切割有以下几种方法: 1.写个定时任务,每天某个时间点把旧的日志重命名,并对服务重启使其重新打开日志并写入. 2.通过管道的方式把新产生的日志写到另外一个日志文件里. 3.通过logrotate ...

  8. 关于ExtJS、JQuery UI和easy UI的选择问题

    转自百度知道. 问:做企业级应用,比如***管理系统,不需要华丽的特效,只希望简单,风格统一.能用到的只有messagebox.tree.grid大概这几个,其他特效不要,忘大神根据自己的见解以及我这 ...

  9. MyBatis_ibatis和mybatis的区别【转】

    1. ibatis3.*版本以后正式改名为mybaits,它也从apache转到了google code下:也就是说ibatis2.*,mybatis3.*. 2. 映射文件的不同 ibatis的配置 ...

  10. 【URAL 1018】Binary Apple Tree

    http://vjudge.net/problem/17662 loli蜜汁(面向高一)树形dp水题 #include<cstdio> #include<cstring> #i ...