c++之最小生成树篇

C++之

最小生成树篇

念:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此的权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树。最小生成树其实是最小权重生成树的简称。

      应用:生成树和最小生成树有许多重要的应用。

例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。

算法:最小生成树有两种算法:1、kruskal(克鲁斯卡尔)算法 和 prim(普里姆)算法

     1、prim(普里姆)算法:

prim算法采用与dijkstra、bellman-ford算法一样的“蓝白点”思想。

所谓“蓝白点”思想就是:“白点代表已经进入最小生成树的点,蓝点表示为进入最小生成树的点。”

算法描述:

 

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:Vnew= {x},其中x为集合V中的任一节点(起始点),Enew= {},为空;
3).重复下列操作,直到Vnew= V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
4).输出:使用集合Vnew和Enew来描述所得到的最小生成树。
2、kruskal(克鲁斯卡尔)算法:
kruskal(克鲁斯卡尔)算法是一种巧妙利用并查集来求最小生成树的算法。
假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
实际应用:
最优布线问题就是一个典型的用最小生成树的例子:
问:
       学校有n台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计算机被连接是指它们中间有数据线连  接。由于计算机所处的位置不同,因此不同的两台计算机的连接费用往往是不同的。当然,如果将任意两台计算机都用数据线连接,费用将是相当庞大的。为了节省费用,我们采用数据的间接传输手段,即一台计算机可以间接的通过若干台计算机(作为中转)来实现与另一台计算机的连接。现在由你负责连接这些计算机,你的任务是使任意两台计算机都连通(不管是直接的或间接的)。
解:
     这道题可以用到prim算法,prim算法就是运用贪心算法,来生成最小生成树。
     
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int g[101][101];
int minn[101];
bool u[101];
int n,j,i;
int main()
{
 cin>>n;
 for(i=1;i<=n;i++)
   for(j=1;j<=n;j++)
     cin>>g[i][j];
 memset(minn,0x7f,sizeof(minn));
 minn[1]=0;
 memset(u,1,sizeof(u));
 for(i=1;i<=n;i++)
 {
  int k=0;
  for(j=1;j<=n;j++)
    if(u[j]&&(minn[j]<minn[k]))
      k=j;
  u[k]=false;
  for(j=1;j<=n;j++)
    if(u[j]&&(g[k][j]<minn[j]))
      minn[j]=g[k][j];
 }
 int total=0;
 for(i=1;i<=n;i++)
   total+=minn[i];
   cout<<total<<endl;
   return 0;
}            
                                                       济南稼轩学校
                                                      39级10班 续尧
 

 

 

 

posted on 2015-07-12 11:32  3910续尧  阅读(210)  评论(0编辑  收藏  举报

导航