求无向连通图的最小生成树 ← Prim算法

这篇具有很好参考价值的文章主要介绍了求无向连通图的最小生成树 ← Prim算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【题目描述】
给定一个 n 个点 m 条边的
无向连通图。图中可能存在重边自环,边权可能为负数
利用Prim算法求此种无向连通图的最小生成树的树边权重之和。

【输入格式】
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含三个整数 u,v,w,表示点 u 和点 v 之间存在一条权值为 w 的边。

【输出格式】
共一行,输出一个整数,表示无向连通图的最小生成树的树边权重之和。

【数据范围】
1≤n≤500,
1≤m≤10^5,
图中涉及边的边权的绝对值均不超过 10000。


【算法代码】
此代码由儿子写于初二暑假期间(2019年7月1日至7月10日间)。

#include <bits/stdc++.h>
using namespace std;

const int maxn=505;
int e[maxn][maxn],dis[maxn],st[maxn];

int inf=0x3f3f3f3f;
int cnt,sum;
int t1,t2,t3,tmp,zx;

int main() {
	int n,m; //n:Number of vertices, m:Number of edges
	cin>>n>>m;
	//Initialize the graph with an adjacency matrix
	for(int i=1; i<=n; i++) //n:Number of vertices
		for(int j=1; j<=n; j++)
			if(i==j) e[i][j]=0;
			else e[i][j]=inf;

	//Input edges and weights
	for(int i=1; i<=m; i++) { //m:Number of edges
		cin>>t1>>t2>>t3; //from,to,weight
		e[t1][t2]=min(e[t1][t2],t3);
		e[t2][t1]=min(e[t1][t2],t3);
	}

	//Initialize the dis array
	for(int i=1; i<=n; i++)
		dis[i]=e[1][i];

	st[1]=1;
	cnt++;
	while(cnt<n) {
		zx=inf;
		for(int i=1; i<=n; i++) {
			if(st[i]==0 && dis[i]<zx) {
				zx=dis[i];
				tmp=i;
			}
		}
		st[tmp]=1;
		cnt++;
		sum+=dis[tmp];

		for(int k=1; k<=n; k++) { //update dis array
			if(st[k]==0 && dis[k]>e[tmp][k])
				dis[k]=e[tmp][k];
		}
	}

	cout<<sum<<endl;
	return 0;
}

/*
in:
6 9
2 4 11
3 5 13
4 6 3
5 6 4
2 3 6
4 5 7
1 2 1
3 4 9
1 3 2

out:
19
-------
in:
5 10
1 2 8
2 2 7
2 1 1
3 4 3
4 4 -10
1 3 -9
5 2 -4
3 1 0
1 4 8
4 4 7

out:
-9
*/


【算法拓展】
若给出的无向图是连通图或
非连通图,且图中可能存在重边自环,边权可能为负数的情形,则可参考YXC大佬的经典Prim算法代码。

#include<iostream>
#include<cstring>
using namespace std;

const int inf=0x3f3f3f3f;
const int maxn=505;
int g[maxn][maxn],dis[maxn];
bool st[maxn];
int n,m,ans;

void prim() {
	memset(dis,inf,sizeof dis);
	for(int i=0; i<n; i++) {
		int t=-1;
		for(int j=1; j<=n; j++) {
			if(!st[j]&&(t==-1||dis[t]>dis[j]))
				t=j;
		}
		st[t]=true;
		if(i && dis[t]==inf) {
			cout<<"impossible"<<endl;
			return;
		}
		if(i) ans+=dis[t];
		for(int j=1; j<=n; j++) {
			dis[j]=min(dis[j],g[t][j]);
		}
	}
	cout<<ans<<endl;
}

int main() {
	cin>>n>>m;
	memset(g,inf,sizeof g);
	
	while(m--) {
		int a,b,c;
		cin>>a>>b>>c;
		g[a][b]=g[b][a]=min(g[a][b],c);
	}
	
	prim();
	
	return 0;
}

/*
in:
10 20
5 3 -8
9 6 -1
1 3 -1
8 7 -6
5 4 6
7 7 -4
4 5 2
10 7 -4
2 1 9
7 10 10
4 5 6
8 7 -7
4 2 -3
9 6 6
5 1 0
7 6 5
5 4 -3
10 8 3
5 3 2
7 8 -7

out:
impossible
-------
in:
5 10
1 2 8
2 2 7
2 1 1
3 4 3
4 4 -10
1 3 -9
5 2 -4
3 1 0
1 4 8
4 4 7

out:
-9
*/





【参考文献】
https://blog.csdn.net/Yu_iChan/article/details/127173866

https://www.acwing.com/problem/content/860/
https://www.acwing.com/blog/content/405/
https://www.acwing.com/solution/content/38312/
https://www.acwing.com/problem/content/solution/860/1/

 






 文章来源地址https://www.toymoban.com/news/detail-466720.html

到了这里,关于求无向连通图的最小生成树 ← Prim算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 求无向图的最小生成树——Kruskal算法(超详细)【并查集,python实现】

    以如下无向图为例,求最小生成树及其权值。 补充知识点: 最小生成树(不官方的解释):包含所有节点,保持整个图连通,所有边权值之和最小。 1、补充在前 (1)图的存储 采用二维列表存储(点,点,边的权值) (2)顶点转换 为了便于计算,将字母A ~ G用数字0 ~ 6代

    2024年02月04日
    浏览(32)
  • 【算法导论】图论(图的基本概念,图上的深度优先搜索(DFS),广度优先搜索(BFS),最小生成树(MST)及Prim,Kruskal算法)

    图(Graph)是一种包含节点与节点的边的集合,记作G=(V,E),V是节点的集合,E是边的集合。 有向图 一个有向图G=(V,E),E中每个元素是V上的一个二值关系:一条从a出发的连向b的边e可以记作一个 有序 对e = (a,b) 。 无向图 一个无向图G=(V,E),E的每个元素e可以表示V上的一个 无序 对,记

    2024年02月03日
    浏览(33)
  • 【学习笔记】无向图的连通性

    定义: 在无向图连通图中,若把点 (x) 删去后整个图就不连通了,则 (x) 为割点(割顶)。 朴素方法: 每次删去一个点,然后判断图是否连通,时间复杂度为 (O(n(n+m))) 。 Tarjan 算法: (dfn_x) : (x) 被 dfs 到的时间戳 (low_x) :在 (x) 及以后被搜索的所有节点的 (low) 值

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

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

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

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

    2024年02月01日
    浏览(37)
  • 最小生成树—Prim算法

    我们要讨论的问题是如何在一个 无向图 中找到它的最小生成树,虽然这个问题对有向图也有意义,但是处理起来更麻烦。 一个无向图 G 的最小生成树就是连接 G 上所有顶点的边构成的树,且这些边的总权值最低。当且仅当图是 连通的 才有最小生成树。 在无向图的最小生成

    2024年02月09日
    浏览(33)
  • 最小生成树——prim算法实现

    N个城市之间需要铺设一张交通网,使任意两个城市间都有交通路线直达,现已知各个城市之间铺设道路的经济成本,问该如何求算铺网的最低经济成本?为求算最低经济成本,可以假设N个城市就是连通网G的N个顶点,而求算最低成本问题可以转化为在N个城市间找到N-1条边,

    2024年02月08日
    浏览(25)
  • Prim算法求最小生成树

    给定一张边带无权的无向图G = (V, E), n = |V|, m = |E|。由V中全部n个顶点和E中n - 1条边构成的无向连通子图被称为G的一课生成树。边的权值之和最小的生成树被称为无向图的最小生成树。 Prim算法总是维护最小生成树的一部分。最初,Prim算法仅确定1号节点属于最小生成树

    2024年02月12日
    浏览(30)
  • Prim算法实现最小生成树

    例如:要在n个城市之间铺设光缆,主要目标是要使这n个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。 将图中所有顶点分为两类:树顶点(已

    2024年02月11日
    浏览(30)
  • 最小生成树(Prim算法,Kruskal算法)

    (1)生成树: 如果在一个无向连通图不包含回路(连通图中不存在环),则为一个树 (2)最小生成树(minimal spanning tree): 在一个图所有生成树中,代价最小的生成树称为最小生成树 (3)生成树的代价: 在一个无向连通网中,生成树各边的权值之和称为该生成树的代价

    2024年02月08日
    浏览(27)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包