最小生成树的性质

MST性质:设G = (V,E)是连通带权图,U是V的真子集。如果(u,v)∈E,且u∈U,v∈V-U,且在所有这样的边中,

(u,v)的权c[u][v]最小,那么一定存在G的一棵最小生成树,(u,v)为其中一条边。

构造最小生成树,要解决以下两个问题:
(1).尽可能选取权值小的边,但不能构成回路(也就是环)。
(2).选取n-1条恰当的边以连接网的n个顶点。

Prim算法的思想:

设G = (V,E)是连通带权图,V = {1,2,…,n}。先任选一点(一般选第一个点),首先置S = {1},然后,只要S是V的真子集,就选取满足条件i ∈S,j ∈V-S,且c[i][j]最小的边,将顶点j添加到S中。这个过程一直进行到S = V时为止。在这个过程中选取到的所有边恰好构成G的一棵最小生成树。

Prim算法代码

以 hdu 1863为例 (点击打开链接

#include<stdio.h>
#include<limits.h>
#include<string.h>
#define N 100
int n,m,map[N+][N+],v[N+],low[N+];
int prim()
{
int i,j,pos,min,s=;
memset(v,,sizeof(v)); //v[i]用来标记i是否已访问,先初始化为0,表示都未访问
v[]=; //先任选一点作为第一个点
pos=; //pos用来标记当前选的点的下标
for(i=;i<=n;i++)
low[i]=map[][i]; //用low数组存已选点到其他点的权值
for(i=;i<n;i++){
min=INT_MAX;
for(j=;j<=n;j++) //求权值最小的边
if(!v[j]&&low[j]<min){
min=low[j];
pos=j;
}
if(min==INT_MAX)
break;
s+=min;
v[pos]=;
for(j=;j<=n;j++) //更新low数组
if(!v[j]&&map[pos][j]<low[j])
low[j]=map[pos][j];
}
if(i!=n)
s=-;
return s;
}
int main()
{
int i,j,s,a,b,c;
while(scanf("%d%d",&m,&n)!=EOF){ //m为道路数,n为村庄数
if(m==)
break;
for(i=;i<=n;i++)
for(j=;j<=n;j++)
map[i][j]=INT_MAX; //先将map数组初始化为很大的值(int 最大值)
for(i=;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=c; //map[a][b]存的从a到b的权值
}
s=prim();
if(s==-)
printf("?\n");
else
printf("%d\n",s);
}
return ;
}

Kruskal算法思想

给定无向连同带权图G = (V,E),V = {1,2,...,n}。

(1)首先将G的n个顶点看成n个孤立的连通分支。将所有的边按权从小大排序。

(2)从第一条边开始,依边权递增的顺序检查每一条边。并按照下述方法连接两个不同的连通分支:当查看到第k条边(v,w)时,如果端点v和w分别是当前两个不同的连通分支T1和T2的端点是,就用边(v,w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看k+1条边。这个过程一个进行到只剩下一个连通分支时为止。此时,已构成G的一棵最小生成树。

Kruskal算法代码:

以 hdu 1863为例 (点击打开链接

 #include<cstdio>
#include<algorithm>
using namespace std;
int f[],n,m;
struct stu
{
int a,b,c;
}t[];
int cmp(struct stu x,struct stu y)
{
return x.c<y.c;
}
int find(int x) //路径压缩,找父节点
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
int krus()
{
int i,k=,s=,x,y;
for(i=;i<=n;i++){
x=find(t[i].a);
y=find(t[i].b);
if(x!=y){ //最小生成树不能形成环,所以要判断它们的是否属于同一集合
s+=t[i].c;
k++;
if(k==m-) //<span style="font-family: KaiTi_GB2312;">最小生成树会形成m-1(顶点-1)条边,若已形成,则最小生成树已构成</span>
break;
f[x]=y; //将父节点更新
}
}
if(k!=m-)
s=-;
return s;
}
int main()
{
int i,s;
while(scanf("%d%d",&n,&m)!=EOF){
if(n==)
break;
for(i=;i<=n;i++)
scanf("%d%d%d",&t[i].a,&t[i].b,&t[i].c);
for(i=;i<=m;i++) //f[i]存的结点i的父亲,先将其父亲都初始化为其本身
f[i]=i;
sort(t+,t++n,cmp); //按权值从小到大排序
s=krus();
if(s==-)
printf("?\n");
else
printf("%d\n",s);
}
return ;
}

注:若顶点数为n,边为e

prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边的数目无关,

而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。


最小生成树之 prim算法和kruskal算法(以 hdu 1863为例)的更多相关文章

  1. 最小生成树之Prim算法和Kruskal算法

    最小生成树算法 一个连通图可能有多棵生成树,而最小生成树是一副连通加权无向图中一颗权值最小的生成树,它可以根据Prim算法和Kruskal算法得出,这两个算法分别从点和边的角度来解决. Prim算法 ...

  2. java实现最小生成树的prim算法和kruskal算法

    在边赋权图中,权值总和最小的生成树称为最小生成树.构造最小生成树有两种算法,分别是prim算法和kruskal算法.在边赋权图中,如下图所示: 在上述赋权图中,可以看到图的顶点编号和顶点之间邻接边的权 ...

  3. 【数据结构】最小生成树之prim算法和kruskal算法

    在日常生活中解决问题经常需要考虑最优的问题,而最小生成树就是其中的一种.看了很多博客,先总结如下,只需要您20分钟的时间,就能完全理解. 比如:有四个村庄要修四条路,让村子能两两联系起来,这时就有最优 ...

  4. 最小生成树(prim算法和kruskal算法)

    学习博客:https://www.cnblogs.com/zhangming-blog/p/5414514.html 其实就是加点法:从不属于这个集合的点中找从本集合可以找到的最小边,加入本集合 看代 ...

  5. 转载:最小生成树-Prim算法和Kruskal算法

    本文摘自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html 最小生成树-Prim算法和Kruskal算法 Prim算 ...

  6. 最小生成树——Prim算法和Kruskal算法

    洛谷P3366 最小生成树板子题 这篇博客介绍两个算法:Prim算法和Kruskal算法,两个算法各有优劣 一般来说当图比较稀疏的时候,Kruskal算法比较快 而当图很密集,Prim算法就大显身手了 ...

  7. 最小生成树Prim算法和Kruskal算法

    Prim算法(使用visited数组实现) Prim算法求最小生成树的时候和边数无关,和顶点树有关,所以适合求解稠密网的最小生成树. Prim算法的步骤包括: 1. 将一个图分为两部分,一部分归为点集 ...

  8. Prim算法和Kruskal算法

       Prim算法和Kruskal算法都能从连通图找出最小生成树.区别在于Prim算法是以某个顶点出发挨个找,而Kruskal是先排序边,每次选出最短距离的边再找. 一.Prim(普里姆算法)算法: ...

  9. Prim算法和Kruskal算法的正确性证明

    今天学习了Prim算法和Kruskal算法,因为书中只给出了算法的实现,而没有给出关于算法正确性的证明,所以尝试着给出了自己的证明.刚才看了一下<算法>一书中的相关章节,使用了切分定理来证 ...

随机推荐

  1. [MarsZ]ThinkPHP项目实战总结

    本文原word格式百度云盘下载地址: http://pan.baidu.com/s/1qYqZFkg 综述 2 需求 2 作者 2 系统一览 2 Unity3d客户端 2 PHP后台 4 准备 6 X ...

  2. linux下用Apache一个IP多个网站多域名配置方法

    如有两个域名,分别是desk.xker.com和tool.xker.com,需把这两个域名都绑定到IP是219.13.34.32的服务器上 1.首先需在域名供应商管理页面指定域名和IP的对应关系 2. ...

  3. Bzoj 2453: 维护队列 && Bzoj 2120: 数颜色 分块,bitset

    2453: 维护队列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 578  Solved: 247[Submit][Status][Discuss] ...

  4. 在MyEclipse配置自己安装的Tomcat(2014.08.18)

    今天因为要在tomcat下运行一个java项目,第一次嘛,遇到了不少问题,总结分享一下: 第一次,我直接将 MyEclipse 生成的项目放到 tomcat 安装目录的 webapps 目录下,运行出 ...

  5. win7IIS错误修改路径最全的

    http://blog.csdn.net/testcs_dn/article/details/8726480 http://www.myexception.cn/asp-dotnet/1341569. ...

  6. Centos6 编译安装局域网NTP服务器

    一.条件及环境: 1.CentOS:我用的是最新的CentOS 6.5 64位版,此教程应该也适用于RedHat 6及CentOS 6系列所有系统: 2.编译所需环境: 1 # yum -y inst ...

  7. JAVA虚拟机简介

    Java虚拟机定义 Java虚拟机有多层含义 一套规范:Java虚拟机规范.定义概念上Java虚拟机的行为表现 一种实现:例如HotSpot,J9,JRockit.需要实现JVM规范,但具体实现方式不 ...

  8. 七个你必须重视的 Git 使用技巧

    与其他技术相比,Git应该拯救了更多开发人员的饭碗.只要你经常使用Git保存自己的工作,你就一直有机会可以将代码退回到之前的状态,因此就可以挽回那些你深夜里迷迷糊糊犯下的错误. 尽管这么说,Git的命 ...

  9. PG数据库之间的导入导出

    本文将介绍如何对PG数据库进行导入.导出,主要利用的是PG自带的pg_dump.pg_dumpall.pg_restore.psql等命令,版本是9.4(不同版本的pg_dump \ pg_resto ...

  10. EL表达式及其定义和使用 转

    作者:http://blog.csdn.net/goskalrie/article/details/51315397 简介 EL(Expression Language)表达式语言实在JSP2.0版本 ...