最小生成树(MST) prim() 算法 kruskal()算法 A - 还是畅通工程
Input
测试输入包含若干测试用例。
每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5 Huge input, scanf is recommended. 下面有一些我写代码时使用到的代码变量:
邻接矩阵(Adjacency Matrix)
无穷大(infinite)
顶点(vertex)
权值(cost)
初始化(initialize)
临时工(temp)
整型最大数值=0x7fffffff
AC代码:
1.prim算法
#include<iostream>
#include<stdio.h>
#define N 110
#define inf 0x7fffffff
int cost[N][N];
int ver[N];
int n,a,b,l,temp,v,k=;
using namespace std;
int initia(){//顶点及储存权值的邻接矩阵的初始化
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if(i==j) cost[i][j]=;
else cost[i][j]=inf;
ver[i]=;
}
ver[]=;
return ;
}
int prim(){
int sumcost=,mincost;
int temp,v;
for(int vsum=1;vsum<n;vsum++)//顶点总数的记录,当所有顶点都被选中时跳出循环
{
mincost=inf;//一个标志用于筛选最小权值的判断条件
for(v=1;v<=n;v++)
{
if(ver[v]==)//所有可选顶点起点的筛选
{
for(int j=1;j<=n;j++)//遍历所有顶点
{
if(cost[v][j]!=&&cost[v][j]<mincost&&ver[j]!=1)//除去自身及不可达的顶点
{
mincost=cost[v][j];//选出最小权值
temp=j;//记录节点
}
}
}
}
ver[temp]=;//顶点标为已经被选中
cost[v][temp]=cost[temp][v]=0;//边标志为已经被选中
sumcost+=mincost;//记录所有路径权值总和
}
cout<<sumcost<<endl;
return ;
}
int main()
{
while(cin>>n&&n!=){
initia();
int t=n*(n-)/;
while(t--){
cin>>a>>b>>l;
cost[a][b]=cost[b][a]=l;
}
prim();
}
return ;
}
用于记录的数组的下标是从1开始的,且注意红色标记地方,vsum的循环次数不要增加,否则会出错!
这里还有一份其他人的代码,红色部分大大减少了运行时的重复次数,没太看懂!
#include<stdio.h>
#include<iostream>
#define INF 99999999
#define N 110
using namespace std;
int n,G[N][N];
void prim()
{
int p[N],vis[N],i,j,v,sum,m,last,k =;
p[k++] = 1;
sum = ;
for(i=;i<=n;i++) vis[i]=;
vis[] = ;
for(m=;m<n;m++)
{
int min = INF;
for(j=0;j<k;j++)
{
v = p[j];
for(i=;i<=n;i++)
{
if(!vis[i]&& G[v][i]<min){
min = G[v][i];
cout<<"cost v"<<v<<" i"<<i<<":"<<G[v][i]<<endl;
last = i;
}
}
}
vis[last] = ;
p[k++] = last;
sum += min;
}
printf("%d\n",sum);
}
int main()
{
int t,m,i,j,a,b,c;
while(scanf("%d",&n),n)
{
for(i=;i<=n;i++){
for(j=;j<=n;j++)
G[i][j] = INF;
}
m = n*(n-)/;
while(m--){
scanf("%d%d%d",&a,&b,&c);
if( c<G[a][b] || c<G[b][a] )//去重边
G[a][b] = G[b][a] = c;
}
prim();
}
return ;
}
2.kruskal算法
这个代码还没有过,我还在找原因
先存着
#include<iostream>
#include<stdio.h>
#define N 110
#define inf 0x7fffffff
int cost[N][N];
int ver[N];
int n,a,b,l,tempi,tempj;
using namespace std;
int initia(){//顶点及储存权值的邻接矩阵的初始化
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if(i==j) cost[i][j]=;
else cost[i][j]=inf;
ver[i]=;
}
return ;
}
int judge(int i,int j){
if(ver[i]==&&ver[j]==) return ;
else return ;
}
int kruskal()
{
int sumcost=,mincost;
for(int esum=;esum<n-;esum++)//边总数的记录,当边的总数为n-1时跳出循环
{
mincost=inf;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(cost[i][j]!=&&cost[j][i]!=&&cost[i][j]<mincost&&cost[j][i]<mincost&&judge(i,j))//除去自身及不可达的顶点
{
mincost=cost[i][j];//选出最小权值
tempi=i;//记录节点
tempj=j;//记录节点
}
ver[tempi]=;//顶点标为已经被选中
ver[tempj]=;//顶点标为已经被选中
cost[tempi][tempj]=cost[tempj][tempi]=;//边标志为已经被选中
sumcost+=mincost;//记录所有路径权值总和
}
cout<<sumcost<<endl;
return ;
}
int main()
{
while(cin>>n&&n!=){
initia();
int t=n*(n-)/;
while(t--){
cin>>a>>b>>l;
cost[a][b]=cost[b][a]=l;
}
kruskal();
}
return ;
}
最小生成树(MST) prim() 算法 kruskal()算法 A - 还是畅通工程的更多相关文章
- 【2018寒假集训Day 8】【最小生成树】Prim和Kruskal算法模板
Luogu最小生成树模板题 Prim 原理与dijkstra几乎相同,每次找最优的点,用这个点去松弛未连接的点,也就是用这个点去与未连接的点连接. #include<cstdio> #in ...
- 【数据结构】 最小生成树(二)——kruskal算法
上一期说完了什么是最小生成树,这一期咱们来介绍求最小生成树的算法:kruskal算法,适用于稀疏图,也就是同样个数的节点,边越少就越快,到了数据结构与算法这个阶段了,做题靠的就是速度快,时间复杂度小. ...
- 最小生成树(prim和kruskal)
最小生成树(prim和kruskal) 最小生成树的最优子结构性质 设一个最小生成树是T.如果选出一个T中的一条边,分裂成的两个树T1,T2依然是它们的点集组成的最小生成树.这可以用反证法来证.反着来 ...
- [贪心经典算法]Kruskal算法
Kruskal算法的高效实现需要一种称作并查集的结构.我们在这里不介绍并查集,只介绍Kruskal算法的基本思想和证明,实现留在以后讨论. Kruskal算法的过程: (1) 将全部边按照权值由小到大 ...
- 无向带权图的最小生成树算法——Prim及Kruskal算法思路
边赋以权值的图称为网或带权图,带权图的生成树也是带权的,生成树T各边的权值总和称为该树的权. 最小生成树(MST):权值最小的生成树. 生成树和最小生成树的应用:要连通n个城市需要n-1条边线路.可以 ...
- 最小生成树(Prim算法+Kruskal算法)
什么是最小生成树(MST)? 给定一个带权的无向连通图,选取一棵生成树(原图的极小连通子图),使生成树上所有边上权的总和为最小,称为该图的最小生成树. 求解最小生成树的算法一般有这两种:Prim算法和 ...
- MST最小生成树及克鲁斯卡尔(Kruskal)算法
最小生成树MST,英文名如何拼写已忘,应该是min spaning tree吧.假设一个无向连通图有n个节点,那么它的生成树就是包括这n个节点的无环连通图,无环即形成树.最小生成树是对边上权重的考虑, ...
- [数据结构]最小生成树算法Prim和Kruskal算法
最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树. 例如,对于如上图G4所示的连通网可以有多棵权值总 ...
- 图的最小生成树的理解和实现:Prim和Kruskal算法
最小生成树 一个连通图的生成树是一个极小的连通子图,它含有图中所有的顶点,但只有足以构成一棵树的n-1条边.我们将构造连通网的最小代价生成树称为最小生成树(Minimum Cost Spanning ...
- hdu 1233 还是畅通工程 最小生成树(prim算法 + kruskal算法)
还是畅通工程 Time Limit: 4000/2 ...
随机推荐
- MongoDB增加数据
MongoDB中出了增加之外,其他的操作都很麻烦. 例子: 1.简单的 db.infos.insert({"url":"www.baidu.com"}); 2. ...
- 如何让Java写的程序,脱离Eclipse在别人的电脑上运行?
Java程序运行,离不开JRE. 将JRE文件夹拷贝出来, 将编写程序的bin文件夹拷贝出来, 再编写一个bat文件. start jre\bin\javaw.exe -cp .\bin\ -Djav ...
- 93.快速搭建Web环境 Angularjs + Express3 + Bootstrap3
转自:https://www.cnblogs.com/wawahaha/p/3946023.html 前言 Angularjs越用越顺手,不仅代码量比jQuery少很多,而且实现思路特别清晰,构建大型 ...
- 乌班图 之 apt命令 及 VMware共享文件夹
apt是Advanced Packaging Tool ,是Ubuntu下的一个安装包管理工具 大部分软件的安装.更新.卸载 都是利用apt命令来实现 直接在终端输入apt即可查阅命令的帮助信息 常用 ...
- tp框架--------where("1")
今天看代码的时候看到一个令我难以理解的sql查询语句,这是tp框架里的 return $this->where("1")->order('ar_id desc')-&g ...
- php获取js里的参数
php获取js的值有如下方式: 1.php echo出js文件得到返回值,在gamemap.js文件中输出参数. echo '<script type="text/javascript ...
- How Javascript works (Javascript工作原理) (二) 引擎,运行时,如何在 V8 引擎中书写最优代码的 5 条小技巧
个人总结: 一个Javascript引擎由一个标准解释程序,或者即时编译器来实现. 解释器(Interpreter): 解释一行,执行一行. 编译器(Compiler): 全部编译成机器码,统一执行. ...
- caioj 1114 树形动态规划(TreeDP)3.0:多叉苹果树【scy改编ural1018二叉苹果树】
一波树上背包秒杀-- #include<cstdio> #include<cstring> #include<algorithm> #include<vect ...
- __weak修饰符
前言 在 HAL 库中,很多回调函数前面使用__weak 修饰符. weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”. 加上了__weak ...
- 洛谷 P2665 [USACO08FEB]连线游戏Game of Lines
P2665 [USACO08FEB]连线游戏Game of Lines 题目背景 Farmer John最近发明了一个游戏,来考验自命不凡的贝茜. 题目描述 Farmer John has chall ...