最小生成树算法prim and kruskal
一.最小生成树定义:
二.最小生成树prim算法
算法思路:step1:假设N=(V,{E})是连通网,TE是N上最小生成树中边的集合。算法从U={u0}(u0属于V),TE={}开始。
step2:在所有的u属于U,v属于V-U的边(u,v)属于E中找一条代价最小的边(u0,v0)并入集合TE。同时v0并入U。
step3:更新边(u,v)的最小值。
step4:c重复step2 and step3直到U=V。
code:
//MiniSpanTree_Prim.cpp
//This function is to create MiniSpanTree_Prim with Prim Algorithm
# include <iostream.h>
# include <malloc.h>
# include <conio.h> # define INFINITY
# define MAX_VERTEX_NUM
# define OK
typedef enum{DG,DN,UDG,UDN} GraphKind;
typedef int EType;
typedef int InfoType;
typedef int VertexType;
typedef int VRType;
typedef int lowcost; typedef struct //define Closedege structure
{ VertexType adjvex;
VRType lowcost;
}Closedge; typedef struct ArcCell //define MGraph structure
{ EType adj;
InfoType *info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct
{ VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum,arcnum;
GraphKind kind;
}MGraph; int CreatUDN(MGraph &G) //CreatUDN() sub-function
{ int IncInfo,i=,j=,k,v1,v2,w;
cout<<endl<<"Please input the number of G.vexnum (eg,G.vexnum=4) : ";
cin>>G.vexnum; //input the number of vex
cout<<"Please input the number of G.arcnum (eg,G.arcnum=4) : ";
cin>>G.arcnum; //input the number of arc
for(i=;i<G.vexnum;++i)
for(j=i;j<G.vexnum;++j)
{ G.arcs[i][j].adj=G.arcs[j][i].adj=INFINITY; //initial weigh
G.arcs[i][j].info=G.arcs[j][i].info=NULL;
}
cout<<"Please input IncInfo (0 for none) : ";
cin>>IncInfo; //if need information, input non-zero
cout<<"Plese input arc(V1-->V2), For example: (V1=1,V2=3),(V1=2,V2=4)..."<<endl;
for(k=;k<G.arcnum;++k) //input arc(v1,v2)
{ cout<<endl<<"Please input the "<<k+<<"th arc's v1 (0<v1<G.vexnum) : ";
cin>>v1;
cout<<"Please input the "<<k+<<"th arc's v2 (0<v2<G.vexnum) : ";
cin>>v2;
cout<<"Please input the "<<k+<<"th arc's weight : ";
cin>>w;
i=v1;
j=v2;
while(i<||i>G.vexnum||j<||j>G.vexnum) //if (v1,v2) illegal
{ cout<<"Please input the "<<k+<<"th arc's v1 (0<v1<G.vexnum) : ";
cin>>v1;
cout<<"Please input the "<<k+<<"th arc's v2 (0<v1<G.vexnum) : ";
cin>>v2;
cout<<"Please input the "<<k+<<"th arc's weight : ";
cin>>w;
i=v1;
j=v2;
} //while end
i--;
j--;
G.arcs[i][j].adj=G.arcs[j][i].adj=w; //
cout<<"G.arcs["<<i+<<"]["<<j+<<"].adj=";
cout<<"G.arcs["<<j+<<"]["<<i+<<"].adj="<<G.arcs[j][i].adj<<endl;
if(IncInfo)
{ cout<<"Please input the "<<k+<<"th arc's Info : ";
cin>>*G.arcs[i][j].info; //input information
}
} //for end
return (OK);
} //CreatUDN() end int Minimum(Closedge *closedge,int Vexnum) //Minimum() sub-function
{ int min=,j; //return min (closedge[min].lowcost)
if(closedge[min].lowcost==)
min++; //closedge[min].lowcost!=0
for(j=;j<Vexnum;++j)
if(closedge[j].lowcost<closedge[min].lowcost
&&closedge[j].lowcost>)
min=j;
return (min);
} //Minimim() end int LocatedVex(MGraph G,VertexType u) //LocatedVex() sub-fuction
{ return (u);
} void MiniSpanTree_Prim(MGraph G,VertexType u) //MiniSpanTree_Prim() sub-function
{ int k,j,i,Vexnum=G.vexnum;
k=LocatedVex(G,u);
Closedge closedge[MAX_VERTEX_NUM];
for(j=;j<G.vexnum;++j) //initial closedge[]
if(j!=k)
{ closedge[j].adjvex=u; // (u,j)
closedge[j].lowcost=G.arcs[k][j].adj;
}
closedge[k].lowcost=; //U include k
for(i=;i<G.vexnum;++i)
{ k=Minimum(closedge,Vexnum); //select k=min(closedge[vi].lowcost)
cout<<endl<<"("<<closedge[k].adjvex+<<","<<k+<<")";
cout<<"="<<G.arcs[closedge[k].adjvex][k].adj;
closedge[k].lowcost=; //U include k
for(j=;j<G.vexnum;++j) //renew closedge[k]
if(G.arcs[k][j].adj<closedge[j].lowcost)
{ closedge[j].adjvex=k;
closedge[j].lowcost=G.arcs[k][j].adj;
} //if end
} //for end
} //Minimun() end void main() //main() function
{ MGraph G;
VertexType u=;
cout<<endl<<endl<<"MiniSpanTree_Prim.cpp";
cout<<endl<<"====================="<<endl;
CreatUDN(G); //call CreatUDN(G) function
cout<<endl<<"The MiniSpanTree_Prim is created as follow order:";
MiniSpanTree_Prim(G,u); //call MiniSpanTree_Prim() function
cout<<endl<<endl<<"...OK!...";
getch();
} //main() end
三.最小生成树kruskal算法
算法思路:step1:假设联通网N=(V,{E}),则领最小生成树的初始状态为只有n个定点而无边的非联通图T=(V,{}),同中每个定点自成一个连通分量。
step2:在E中选择代价最小的边,若改边的定点落在T中不同的连通分量上,则将此边加入到T中,否则舍弃此边而选择下一条代价最小的边。
step3:依次类推知道T中所有定点都在同一连通分量上。
时间复杂度:O(eloge)
#include<iostream>
#include<vector>
#include<map>
using namespace std;
class edge
{
public:
edge(char a,char b,int wight):ma(a),mb(b),mwight(wight){}
edge(const edge &other)
{
ma = other.ma;
mb = other.mb;
mwight = other.mwight;
}
edge & operator=(const edge & other)
{
ma = other.ma;
mb = other.mb;
mwight = other.mwight;
return *this;
}
char getma()
{
return ma;
}
char getmb()
{
return mb;
}
private:
char ma;
char mb;
int mwight;
}; void kruskal(vector<edge> & edges,map<char,int> & vertexs,vector<edge> &myedge)
{ vector<edge>::iterator begin = edges.begin();
for (;begin != edges.end(); begin++)
{
int vera = vertexs[begin->getma()];
int verb = vertexs[begin->getmb()];
if ( vera != verb)
{
myedge.push_back(*begin);
map<char,int>::iterator item = vertexs.begin();
for(;item != vertexs.end();item++)
{
if (item->second == vera)
{
item->second = verb;
}
}
}
}
} void main()
{
char ch;
int i;
edge edges[] = {
edge('a','c',),
edge('d','f',),
edge('b','e',),
edge('c','f',),
edge('a','d',),
edge('c','d',),
edge('c','b',),
edge('a','b',),
edge('c','e',),
edge('c','f',)
};
map<char,int> vertex;
vector<edge> myedges(edges,edges+sizeof(edges)/sizeof(edge)),result;
for( ch='a', i =;i<;ch++,i++)
{
vertex.insert(std::pair<char,int>(ch,i));
}
kruskal(myedges,vertex,result);
for (vector<edge>::iterator start = result.begin(); start != result.end(); start++)
{
cout<<start->getma()<<"--"<<start->getmb()<<" "<<endl;
}
}
最小生成树算法prim and kruskal的更多相关文章
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...
- [数据结构]最小生成树算法Prim和Kruskal算法
最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总 ...
- 最小生成树(prim和kruskal)
最小生成树(prim和kruskal) 最小生成树的最优子结构性质 设一个最小生成树是T.如果选出一个T中的一条边,分裂成的两个树T1,T2依然是它们的点集组成的最小生成树.这可以用反证法来证.反着来 ...
- 最小生成树算法 prim kruskal两种算法实现 HDU-1863 畅通工程
最小生成树 通俗解释:一个连通图,可将这个连通图删减任意条边,仍然保持连通图的状态并且所有边权值加起来的总和使其达到最小.这就是最小生成树 可以参考下图,便于理解 原来的图: 最小生成树(蓝色线): ...
- 数据结构(三十三)最小生成树(Prim、Kruskal)
一.最小生成树的定义 一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边. 在一个网的所有生成树中,权值总和最小的生成树称为最小代价生成树(Minimum ...
- 最小生成树,Prim和Kruskal的原理与实现
文章首先于微信公众号:小K算法,关注第一时间获取更新信息 1 新农村建设 大清都亡了,我们村还没有通网.为了响应国家的新农村建设的号召,村里也开始了网络工程的建设. 穷乡僻壤,人烟稀少,如何布局网线, ...
- 【2018寒假集训Day 8】【最小生成树】Prim和Kruskal算法模板
Luogu最小生成树模板题 Prim 原理与dijkstra几乎相同,每次找最优的点,用这个点去松弛未连接的点,也就是用这个点去与未连接的点连接. #include<cstdio> #in ...
- 最小生成树算法——prim算法
prim算法:从某一点开始,去遍历相邻的边,然后将权值最短的边加入集合,同时将新加入边集中的新点遍历相邻的边更新边值集合(边值集合用来找出新的最小权值边),注意每次更新都需将cost数组中的点对应的权 ...
- 最小生成树(prim和Kruskal操!!SB题)
Arctic Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 30571 Accepted: 9220 D ...
随机推荐
- vi/vim编辑器的基本操作
vi/vim编辑器的基本操作 Contents 1. 工具准备(下载gvim) 2. vi/vim基本入门 2.1. 安装 2.2. 基本使用 3. vi/vim基本命令表 1 工具准备(下载gvim ...
- Ajax.BeginForm的异步提交数据 简介
Html.BeginForm与Ajax.BeginForm都是MVC架构中的表单元素,它们从字面上可以看到区别,即Html.BeginForm是普通的表单提交,而Ajax.BeginForm是支持异步 ...
- mysql_常用命令
1: 以指定编码创建数据库 CREATE DATABASE `search_data` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
- 前端学习笔记(zepto或jquery)——对li标签的相关操作(四)
对li标签的相关操作——五种方式给奇数项li标签设置样式 demo演示: 1 2 3 4 5 6 7 // 详解: 通常我们为多个li添加样式时常用的是使用filter,但我们在第三节中可以看到fil ...
- Asp.net MVC + EF + Spring.Net 项目实践(四)
这篇写一写如何使用Spring.net来解耦各个项目 1. 在接口层添加IStudentBLL文件,里面有GetStudent和GetAllStudents两个方法:然后在StudentBLL类里实现 ...
- 吐槽一下项目中的代码坏味道:滥用java常量
我们的项目中是否充斥着类似以下的代码呢?定义一个专门存放常量的java类(接口),非常多其它类依赖该常量类. public interface IConstant { int ZERO = 0; St ...
- angularJS之站在jQuery的肩膀上
jQuery:用更少的代码,实现更强悍的功能 托互联网日新月异发展的福,浏览器变成了人们接入互联网的入口,而JavaScript 这个曾经的小语种,终于成功地站到了舞台的中央,唤起了开发者的兴趣. 浏 ...
- MySQL 存储过程 经常使用语法
MySQL 存储过程是从 MySQL 5.0 開始添加的新功能.存储过程的长处有一箩筐.只是最基本的还是运行效率和SQL 代码封装.特别是 SQL 代码封装功能,假设没有存储过程,在外部程序訪问数据库 ...
- ASP.NET状态服务及session丢失问题解决方案总结
原文:ASP.NET状态服务及session丢失问题解决方案总结[转载] asp.net Session的实现: asp.net的Session是基于HttpModule技术做的,HttpModule ...
- SqlDataReader的关闭问题
原文:SqlDataReader的关闭问题 昨天一个朋友使用Repeater绑定数据源时,老是出现"阅读器关闭时尝试调用 FieldCount 无效."错误. 我看了他的代码,使用 ...