C++数据结构——习题6-5 最小生成树(Prim算法)

这篇具有很好参考价值的文章主要介绍了C++数据结构——习题6-5 最小生成树(Prim算法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

习题6-5 最小生成树

省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。已知村庄数N和可建道路数M,设初始状态下任意村庄之间没有路,请编写程序,根据输入的两村庄间修建道路的费用情况,计算这些村庄畅通所需要的最低成本。

输入格式:

测试数据有多组。每组测试数据第1行输入村庄数目N ( 1< N < 11 )和道路数M;随后的M行输入村庄间道路的成本,每行给3个正整数,分别是两个村庄的编号(从1编号到N),修建此两村庄间道路的成本(不超过50)。当输入0 0时,表示输入结束。

输出格式:

对于每组测试,输出这些村庄畅通所需要的最低成本。

输入样例:
3 3
1 2 1
1 3 2
2 3 4
0 0
输出样例:
3
出处:

HDOJ

代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB

解题代码

#include<bits/stdc++.h>
using namespace std;
int n;
struct MAP{
	int Gmap[50][50];
}G;//创建图
//获取此时dist中最短的路径节点
int getMinPoint(int *dist,bool *visited)
{
	int k=-1,min=INT_MAX;
	for(int i=1;i<=n;i++){
		if(dist[i]<min&&visited[i]==false){
			k=i;
			min=dist[i];
		}
	}
	return k;
}
//prime算法
void prime(int t){
	bool visited[n+1];
	int dist[n+1];
	int adjvex[n+1];
	for(int i=1;i<=n;i++){
		dist[i]=G.Gmap[t][i];
		visited[i]=false;
		if(G.Gmap[t][i]<INT_MAX) adjvex[i]=t;
		else adjvex[i]=-1; 
	}
	int k; 
	visited[t]=true;
	dist[t]=0;//初始起点位置要置为0
	for(int i=1;i<n;i++){
		k=getMinPoint(dist,visited);
		visited[k]=true;
		for(int j=1;j<=n;j++){
			if(dist[j]>G.Gmap[k][j]&&!visited[j]){
				dist[j]=G.Gmap[k][j];
				adjvex[j]=k;
			}
		}
	}
	int ans=0;//求和得出结果。
	for(int i=1;i<=n;i++){
		ans+=dist[i];
	}
	cout<<ans<<endl;
}
int main()
{
	int m,a,b,w;
	while(cin>>n>>m&&n!=0&&m!=0){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				G.Gmap[i][j]=INT_MAX;
			}
		}
		for(int i=0;i<m;i++){
			cin>>a>>b>>w;
			G.Gmap[a][b]=w;
			G.Gmap[b][a]=w;
		}
		prime(1);
	}
}

解题思路
按照prime算法的思路,假设我们有这样一张连通图,如下:
C++数据结构——习题6-5 最小生成树(Prim算法)
那么我们创建邻接表的时候,就应该的得到如下表一样的结果:

坐标 1 2 3 4 5 6
1 INT_MAX 7 INT_MAX INT_MAX 2 1
2 7 INT_MAX 4 INT_MAX 8 INT_MAX
3 INT_MAX 4 INT_MAX 7 7 INT_MAX
4 INT_MAX INT_MAX 7 INT_MAX 5 5
5 2 8 7 5 INT_MAX 3
6 1 INT_MAX INT_MAX 5 3 INT_MAX

我们的算法prim算法的思想核心就是生成一个顶点集合G={U},然后初始集合添加起始顶点U,在图中找到以U为起点的最近的一条边,将终点加入到集合G中,然后再以集合中的顶点为起点的所有路径中找最短边且不再集合中(不形成环路)的点加入集合,依次类推,直至加入所有顶点。
举例:
起始G={1};
我们根据邻接表和绘制的图,可以看出,最近的是6,我们将6加入到集合,得到G={1,6};
C++数据结构——习题6-5 最小生成树(Prim算法)

我们看1和6,他们的最小边是(1,5)这一条边,那么我们将5加入到集合G,得到G={1,6,5}
C++数据结构——习题6-5 最小生成树(Prim算法)

继续可以看到最短边为(5,6)但是,两个顶点都在集合中,形成了环路,不可取,于是取(5,4),因为最小二叉树形态不唯一,所以也可以取(6,4),一般取小。得到G={1,6,5,4}
C++数据结构——习题6-5 最小生成树(Prim算法)
然后(1,2),(5,3),(4,3)都为7,那么取小原则,就取(1,2)得到G={1,6,5,4.2}
C++数据结构——习题6-5 最小生成树(Prim算法)
最有一个节点三,取短的就是(2,3)了,得到G={1,6,5,4,2,3},最终我们得到一个最小二叉树乳如下:
C++数据结构——习题6-5 最小生成树(Prim算法)
代码中void prime(int t)函数,有三个数组,bool visited记录是否已将这个节点加入集合。int dist集合中连通的最短路径。int adjvex存储节点的上一跳节点。
假设初始t=1
我们的dist数组初始化为INT_MAX,最大整数,然后visited设置为false,都没有找过,可以得到如下的数组:

下标 1 2 3 4 5 6
dist 0 7 INT_MAX INT_MAX 2 1
visited true false false false false false
adjvex -1 1 -1 -1 1 1

这里dist[1]一定要是0,因为是起点,并不加入求代价的计算,所以要0.
然后我们调用了函数getMinPoint(dist,visited),就是找当前的dist中最短的路径,然后返回最短路径的终点,前提是这个点不在我们的集合里,k等于返回的值

k=getMinPoint(dist,visited);
visited[k]=true;

然后我们这里应该就得到k=6;将visited[6]=true;
去找6的所有路径中,小于当前dist的路径信息,修改dist,得到如下表:

下标 1 2 3 4 5 6
dist 0 7 INT_MAX 5 2 1
visited true false false false false true
adjvex -1 1 -1 6 1 1
for(int j=1;j<=n;j++){
			if(dist[j]>G.Gmap[k][j]&&!visited[j]){
				dist[j]=G.Gmap[k][j];
				adjvex[j]=k;
			}
		}

然后同样调用getMinPoint(dist,visited);一直重复直至所有的节点都调用完了,执行了n-1次后,得到如下表所示的结果:

下标 1 2 3 4 5 6
dist 0 7 4 5 2 1
visited true true true true true true
adjvex -1 1 2 5 1 1

C++数据结构——习题6-5 最小生成树(Prim算法)

思路差不多这个思路,大家可以带一下值进去就好理解了,这里我就不多说了,如果有问题请及时指出!文章来源地址https://www.toymoban.com/news/detail-486448.html

到了这里,关于C++数据结构——习题6-5 最小生成树(Prim算法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最小生成树Kruskal、Prim算法C++

    连通图: 在无向图中,若从顶点v1到顶点v2有路径,则称顶点v1和顶点v2是连通的。如果图中任意一对顶点都是连通的,则称此图为连通图。 生成树: 一个连通图的最小连通子图称作为图的生成树。有 n个顶点 的连通图的生成树有 n个顶点和 n-1 条边。 最小生成树: 最小生活

    2024年02月10日
    浏览(28)
  • 数据结构与算法课程设计---最小生成树的应用

    1.问题 假定有这么一个问题,有11个城市,城市之间有一些天然气管道,铺设天然气管道需要花费不同的金额,现在要你选择其中一些天然气管道,使得所有城市可以互相联通且花费最小。 2.分析 我们把这个问题抽象为一张图,每个城市是一个顶点,城市与城市之间的管道是

    2024年02月08日
    浏览(36)
  • 【数据结构与算法】图的搜索——广度优先遍历、最小生成树

    邻接链表: 用字典实现.有向图的邻接链表的总长度等于图的边个数;无向图的邻接链表的总长度等于图的边个数的2倍. 邻接矩阵:用于最短路径算法. 该数据结构维护一个不相交动态集的集合,每个集合有一个代表,不关心谁做代表。 支持三种操作: MAKE_SET(x) FIND_SET(x) UNION(x,y

    2024年02月19日
    浏览(32)
  • 【数据结构】无向图的最小生成树(Prime,Kruskal算法)

    连通图 :在 无向图 中,若从顶点v1到顶点v2有路径,则称顶点v1与顶点v2是连通的。如果图中 任意一对顶点都是连通的 ,则称此图为连通图 强连通图 :在 有向图 中,若在每一对顶点vi和vj之间都存在一条从vi到vj的路径,也存在一条从vj到vi的路径,则称此图是强连通图 生成

    2024年01月24日
    浏览(32)
  • 数据结构(Java)最小生成树(普里姆、克鲁斯卡尔算法)

    最小生成树 (Minimum Cost Spanning Tree) ,简称 MST 。 1) 给定一个带权的无向连通图 , 如何选取一棵生成树 , 使树上所有 边上权的总和为最小 ,就 叫最小生成树 2) N 个顶点,一定有 N-1 条边 3) 包含全部顶点 4) N-1 条边都在图中 (好像不能形成闭合回路) 求最小生成树的算法主要是

    2023年04月08日
    浏览(26)
  • 数据结构---最小生成树((普里姆算法)C语言看了就懂教程)

        普里姆算法就是“加点法”,是一种将连通网转换成最小生成树的一种算法     在一个连通图的所有生成树中,各边代价之和最小的那颗生成树称为该连通图的最小代价生成树(MST)     ①对于任意一张连通图,假设 N = (V,E)是连通网,TE就是最小生成树中边的集合    

    2024年02月03日
    浏览(28)
  • 考研算法复试刷题19天:Prim算法求最小生成树 【prim,最小生成树】

    参考博客:图解:什么是最小生成树? - 知乎 (zhihu.com)  总结下来的过程就是,一张图,我们将他化为树的形式,也就是生成树。那么最小生成树有是啥呢? 所谓一个 带权图 的最小生成树,就是原图中边的权值最小的生成树 ,所谓最小是指边的权值之和小于或者等于其它

    2024年02月07日
    浏览(45)
  • (数据结构)普利姆算法(Prim)实现

    假设要在n个城市之间建立通信联络网,每两个城市之间建立线路都需要花费不同大小的经费,则连通n个城市只需要n-1个条线路,最小生成树解决的问题就是: 如何在最节省经费的前提下建立这个通信网 也可以理解为:n个城市之间最多可以建立n(n-1)/2条线路,我们要从这里挑

    2024年02月03日
    浏览(33)
  • 数据结构——普里姆(Prim)算法

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树。意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权值之和亦为最小。 以下是数据结构中关于普里姆算法的操作(编程风格参考严蔚敏版数据结构)

    2024年02月06日
    浏览(33)
  • 贪心算法:最小生成树Prim算法

    👨‍🎓作者简介:一位喜欢写作,计科专业大二菜鸟 🏡个人主页:starry陆离 🕒首发日期:2022年5月31日星期二 🌌上期文章:动态规划:多重背包问题 📚订阅专栏:算法分析与设计 如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦 这是大一暑假的c笔记,再一次写pri

    2024年02月01日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包