C++ 图的算法 最小生成树之Prim(普里姆)算法

转载自C++ 最小生成树之Prim(普里姆)算法

最小生成树: 是在一个给定的无向图G(V,E)中求一棵树T,使得这棵树拥有图G中的所有顶点,且所有边都是来自图G中的边,并且满足整棵树的边权之和最小。

最小生成树的性质:

  1. 最小生成树是树.边数是点数减1.树中不存在环.
  2. 最小生成树不唯一.但是权值一定相同.
  3. 根节点可以是任意一个节点.

基本思想

  • 对图G(V,E)设置集合S,存放已经被访问的顶点,然后每次从集合V-S中选择与集合S的最短距离最小的一个顶点(记为u),访问并加入集合S。
  • 之后,令顶点u为中介点,优化所有从u能到达的顶点v与集合S之间的最短距离
  • 这样的操作执行n次(n为顶点个数),直到集合S已包含所有顶点。

邻接矩阵实现的Prim算法

/*
	n 顶点数
	s 源点
	G 图的邻接矩阵
	visited 是否被访问.就是加入集合S中
	d 存储顶点和几何S的最短距离
*/
int Prim(int n, int s, vector<vector<int>> G,
	vector<bool>& visited, vector<int> &d) {

	// 初始化为最大值
	fill(d.begin(), d.end(), INT_MAX);
	d[s] = 0; // 表示把源点放入集合S中.
	int sum = 0; // 最小生成树的权之和

	// 循环n次依次找到n个点
	for (int i = 0; i < n; i++) {
		int u = -1; // u点: V中的u到S的距离最小
		int MIN = INT_MAX;  // 最小的距离是多少d[u]
		// 找到最小值d[j]
		for (int j = 0; j < n; j++) {
			// 没有遍历过
			if (visited[j] == false && d[j] < MIN) {
				MIN = d[j];
				u = j;
			}
		}
		// 如果找不到d[j],说明不连通
		if (u == -1) {
			return -1;
		}
		visited[u] = true; // 把u加入集合S中.
		sum += d[u];
		// 更新这个新加入的点能达到的距离
		for (int v = 0; v < n; v++) {
			// v未访问过,新加入的节点能使d[v]变小
			if (visited[v] == false && G[u][v] < d[v]) {
				d[v] = G[u][v];
			}
		}
		return sum;
	}
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值