最小生成树——prim

prim:逐“点”生成最小生成树

与Dijkstra不同的是:加入点到生成树中,不要考虑与源点的距离,而是考虑与生成树的距离

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

const int VERTEX_NUM = 20;
const int INFINITY = 0x7fffffff;

bool vis[VERTEX_NUM];
int dist[VERTEX_NUM]; 
int pre[VERTEX_NUM];

class Graph {
public:
	int vexNum;
	int edgeNum;
	int vex[VERTEX_NUM];
	int arc[VERTEX_NUM][VERTEX_NUM]; 
};

void createGraph(Graph &G)
{
	cout << "please input vexNum and edgeNum: ";
	cin >> G.vexNum >> G.edgeNum;
	for (int i = 0; i != G.vexNum; ++i) {
		cout << "please input no" << i+1 << " vertex: ";
		cin >>  G.vex[i];					// 自定义顶点序号 
	}
	for (int i = 0; i != G.vexNum; ++i) {
		for (int j = 0; j != G.vexNum; ++j) {
			G.arc[i][j] = INFINITY;
		}
	}
	for (int k = 0; k != G.edgeNum; ++k) {
		cout << "please input the vertex of edge(vi, vj) and weight: ";
		int i, j, w;
		cin >> i >> j >> w;
		G.arc[i][j] = w;
		G.arc[j][i] = G.arc[i][j];			
	}
}

void prim(Graph &G, int src)
{
	memset(dist, INFINITY, VERTEX_NUM);
	memset(vis, false, true);
	for (int i = 0; i != G.vexNum; ++i) {
		pre[i] = src;
		dist[i] = G.arc[src][i];
	}
	vis[src] = true;
	int lowcost;
	int lowcostIndex;
	for (int cnt = 1; cnt != G.vexNum; ++cnt) {
		lowcost = INFINITY;
		for (int i = 0; i != G.vexNum; ++i) {
			if (dist[i] < lowcost && !vis[i]) {
				lowcost = dist[i];		// 没意义,最小生成树考虑的是到生成树而不是源点 
				lowcostIndex = i;
			}
		}
		vis[lowcostIndex] = true;
		for (int i = 0; i != G.vexNum; ++i) {
			if (G.arc[lowcostIndex][i] != INFINITY && G.arc[lowcostIndex][i] < dist[i] && !vis[i])
				dist[i] = G.arc[lowcostIndex][i];
				pre[i] = lowcostIndex;
		}
	}
}


int main()
{
	Graph G;
	createGraph(G);
	int src = 0;
	prim(G, src);
	int sum = 0;
	for (int i = 0; i != G.vexNum; ++i) {
		if (src == i) continue;
		sum += dist[i];
	}
	cout << sum << endl;
} 

  

原文地址:https://www.cnblogs.com/xzxl/p/8652293.html