最小生成树算法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 ...
随机推荐
- 包装类、Object类——Java笔记(八)
包装类: 基本数据类型的包装类 基本数据类型 包装类 byte Byte short Short int Integer long Long char Character float ...
- cocos2d-x-2.2的SimpleAudioEngine::sharedEngine()->playEffect()计划中断bug
在该计划已经正常,但现在突然发iphone播放声音上就挂了.播放音乐是没有问题的. android没问题. xcode给定的位置,如下面的附图: 网上搜了一下,说是有全局断点造成的.于是command ...
- css+html菜单适应性学习的宽度
本文就是利用css和html自适应于文本菜单的长度. 后效果图实现,例如下列: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvajkwMzgyOTE4Mg= ...
- sscanf()函数的用法
来自:http://blog.csdn.net/tigerjibo/article/details/6442151 sscanf 名称: sscanf() - 从一个字符串中读进与指定格式相符的数据. ...
- 大数据系列修炼-Scala课程07
由于昨天下班后有点困,就没有来及写博客,今天会把它补上!把这个习惯坚持下去! 关于Scala高阶函数详解 1.Scala高阶函数代码实现:高阶函数就是在我们函数中套用函数 2.高阶函数代码详解:高阶函 ...
- int 价值型追记-time
一个 30 M 的int号码值一次性保存.和读取一次,避免保存为char 种类,进行格转变,格转换时间是非常耗时. #include <iostream> #include <fst ...
- HDU 5037 FROG (贪婪)
Problem Description Once upon a time, there is a little frog called Matt. One day, he came to a rive ...
- BZOJ 3689 异或 Trie木+堆
标题效果:特定n的数量,这种需求n数22 XOR的值前者k少 首先,我们建立了一个二进制的所有数字Trie木,您可以使用Trie木size域检查出一些其他的数字XOR值首先k少 然后,我们要保持一个堆 ...
- vim添加自己//解决方案
使用vim从外面将代码复制并粘贴到时间,假设有一排//凝视.自己主动下一行加入//和每行增加一个<tab>.格全乱:其他编辑器*.c *cpp其他文件格当公式,假设有一排//凝视,按o换行 ...
- swift 注意事项 (十六) —— 可选链
可选链(Optional Chaining) 我们都知道"可选型"是什么.那么可选链又是什么,举个样例解释一下: struct MyName{ var name } st ...