最小生成树-Prim算法

最小生成树的3个性质:

1、最小生成树是一棵树,其边数等于顶点数-1,且树内一定不会有环

2、对给定的图G,其最小生成树可以不唯一,但其边权之和一定是最小的,唯一的

3、最小生成树是在无向图中生成的,因此其根结点可以是这颗树上任意一个结点;因此,为了让最小生成树唯一,题目一般会给定一个根结点

Prim算法和Dijkstra算法思想基本一样,只不过dis[]的数组含义不一样罢了

代码如下:

#include"stdafx.h"
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 500;
const int INF = 1e9;
int Vertexnum, Edgenum, Start;//顶点数、边数、起点
struct node {//结点结构体
	int v;
	int weight;
};
vector<node> adj[maxn];//邻接表存储图
int dis[maxn];//顶点与集合s的最短距离
bool vis[maxn] = { false };//标记顶点v是否被加入生成树中
int Prim(int s) {//s代表根结点
	fill(dis, dis + maxn, INF);//初始化
	dis[s] = 0;
	int sumweight = 0;//存放最小生成树的边权之和
	for (int i = 0; i < Vertexnum; i++) {
		int u = -1, min = INF;
		for (int j = 0; j < Vertexnum; j++) {
			if (vis[j] == false && dis[j] < min) {
				u = j;
				min = dis[j];
			}
		}
		if (u == -1)return -1;
		vis[u] = true;
		sumweight += dis[u];
		for (int j = 0; j < adj[u].size(); j++) {
			int v = adj[u][j].v;
			int weight = adj[u][j].weight;
			if (vis[v] == false && weight < dis[v]) {
				dis[v] = weight;
			}
		}
	}
	return sumweight;
}
int main() {
	cin >> Vertexnum >> Edgenum >> Start;
	int start, end, weight;//起点、终点、边权
	for (int i = 0; i < Edgenum; i++) {
		cin >> start >> end >> weight;
		node N1;
		N1.v = end;
		N1.weight = weight;
		adj[start].push_back(N1);
		node N2;
		N2.v = start;
		N2.weight = weight;
		adj[end].push_back(N2);
	}
	cout << Prim(Start);//输出最小生成树边权和
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值