数据结构——图的最小生成树

一、最小生成树的概念

图分为无向图和有向图,其中包括无权,有权(正权负权)图。

 定义:无向带权图G顶点个数为 m ,由G中 m 个点和 m - 1 条边构成的连通子图称为G的一条支撑树,也叫生成树。 边权之和最小的支撑树叫做最小支撑树(MST)。

最小支撑树无回路 

二、算法分析

 1.Prim算法(逐点加入)

Prim算法更适用于稠密图(点少边多)。

过程图解

 

2.Kruskal算法(逐边加入)

利用并查集实现,将每个连通分量看作一个集合,顶点看作集合元素,每次查询一条权值最小的边,查询该边的两端是否在同一个集合内,若不在就将这两个集合合并,将该边加入支撑树中。Kruskal算法更适用于稀疏图(点多边少)。

 过程图解

 

三、求最小支撑树例题——Prim

1. 题目说明

 2. 代码实现


#include<iostream>
using namespace std;
#define WQ 65535//有符号的最大值表示无穷大

int edge[2000][2000];//邻接矩阵
long long sum;//权值之和
int TE[1000];
int lowcost[2000];//最小权值数组 
int U[2000];
bool flag = false;
//构建邻接矩阵
void CreatGraph(int n, int e) {

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			edge[i][j] = WQ;
		}
	}
	for (int k = 0; k < e; k++) {
		int a, b, c;
		cin >> a >> b >> c;
		edge[a][b] = c;
		edge[b][a] = edge[a][b];
	}
}
void Prim(int n, int e) {
	flag = false;
	for (int i = 1; i <= n; i++) {
		lowcost[i] = edge[1][i];
		U[i] = 1;
	}
	U[1] = -1;
	int k = 1;
	for (int i = 1; i <= n - 1; i++) {
		int v = 0;
		int min = WQ;//无穷大
		for (int j = 1; j <= n; j++) {
			if (U[j] != -1 && lowcost[j] < min) {//初始化
				v = j;
				min = lowcost[j];
			}
		}
		if (v == 0) {
			flag = true;
			printf("There is no minimum spanning tree.\n");
			return;
			//图不连通
		}
		TE[k] = lowcost[v];
		k = k + 1;
		lowcost[v] = 0;
		U[v] = -1;
		for (int j = 1; j <= n; j++) {
			if (U[j] != -1 && edge[v][j] < lowcost[j]) {//更新权值
				lowcost[j] = edge[v][j];
				U[j] = v;
			}
		}
	}

	//return 0;
}

//主函数
int main() {
	int n;//顶点数
	int e;//边数
	while (scanf("%d%d", &n, &e) != EOF)
	{
		CreatGraph(n, e);//构建邻接矩阵
		Prim(n, e);
		if (flag == false) {
			for (int i = 1; i <= e; i++) {
				sum += TE[i];
			}
			cout << sum << endl;
		}
	}
	return 0;
}

  • 3
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值