Prim's minimum spanning tree algorithm

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <climits>

using namespace std;

typedef struct
{
	int head;
	int tail;
	int cost;
} Edge;

int heap[3000];
int prior[3000];
int heapSize = 0;
int id2Pos[3000];
bool boolVist[3000];
void InsertHeap(int id)
{
	heap[heapSize++] = id;
	id2Pos[id] = heapSize-1;

	int pos = heapSize-1;
	while(pos > 0)
	{
		int parent = pos-1 >> 1;
		if (prior[id] > prior[heap[parent]])
			break;

		int temp = heap[parent];
		heap[parent] = id;
		heap[pos] = temp;

		id2Pos[id] = parent;
		id2Pos[temp] = pos;

		pos = parent;
	}
}

void DeleteHeap(int id)
{
	int pos = id2Pos[id];
	if (pos < 0)
		return;

	heap[pos] = heap[--heapSize];
	id2Pos[heap[pos]] = pos;
	while(pos < (heapSize>>1))
	{
		int child = 2*pos +1;
		if (child+1 < heapSize && prior[heap[child+1]] < prior[heap[child]])
			child++;

		if (prior[heap[pos]] <= prior[heap[child]])
			break;

		int temp = heap[pos];
		heap[pos] = heap[child];
		heap[child] = temp;

		id2Pos[temp] = child;
		id2Pos[heap[pos]] = pos;

		pos = child;
	}

}

int PopMin()
{
	int id = heap[0];
	DeleteHeap(id);

	return id;
}

// --------------------------------------
int PrimMST(vector<vector<int>> &V, vector<Edge> &E)
{
	int nV = V.size();
	int nE = E.size();
	// ---- Initialize ------
	/*for (int i = 0; i<nV; i++)
	{
	int m = INT_MAX;
	for (int j=0; j<V[i].size(); j++)
	{
	if (m < E[V[i][j]].cost)
	m = E[V[i][j]].cost;
	}

	prior[i] = m;
	InsertHeap(i);
	}*/

	for (int i=0; i < nV; i++)
	{
		prior[i] = INT_MAX;
		id2Pos[i] = -1;
		boolVist[i] = false;
	}

	int mE = INT_MAX;
	int idmE = 0;
	for (int i=0; i<nE; i++)
	{
		if(mE > E[i].cost)
		{
			mE = E[i].cost;
			idmE = i;
		}
	}

	prior[E[idmE].head-1] = mE; 
	InsertHeap(E[idmE].head-1);
	// --------- Prim ----------------
	int smst = -mE;
	while(heapSize >0)
	{
		int u = PopMin();
		smst += prior[u];
		boolVist[u] = true;

		for (int i=0; i<V[u].size(); i++)
		{
			int s = E[V[u][i]-1].head -1;
			int v = E[V[u][i]-1].tail -1;
			int c = E[V[u][i]-1].cost;

			if (!boolVist[s])
			{
				DeleteHeap(s);
				prior[s] = min(prior[s], c);
				InsertHeap(s);
			}

			if (!boolVist[v])
			{
				DeleteHeap(v);
				prior[v] = min(prior[v], c);
				InsertHeap(v);
			}
		}
	}

	return smst;
}


int main()
{
	ifstream infile;
	infile.open("edges.txt");

	// ------------------------ 
	string line;
	std::stringstream ss;
	getline(infile, line);
	ss << line;

	int nV, nE;
	ss >> nV;
	ss >> nE;

	// ------- Initialize ------------
	vector<vector<int>> V(nV);
	vector<Edge> E(nE); 
	// -------------------------------
	ss.clear();
	line.clear();
	int n =0;
	while(getline(infile, line) && n<nE)
	{
		ss << line;

		int h;
		int t;
		int c;		
		ss >> h;
		ss >> t;
		ss >> c;

		E[n].head = h;
		E[n].tail = t;
		E[n].cost = c;

		V[h-1].push_back(n+1);
		V[t-1].push_back(n+1);

		n++;
		ss.clear();
		line.clear();
	}


	// -----------------------------------
	int cmst = PrimMST(V, E);

	cout << cmst << endl;
	/*for (vector<int>::iterator it = mst.begin(); it != mst.end(); it++)
	{
	cout << *it << endl;
	}*/
	// -----------------------------------

	infile.close();

	return 0;
}


参考:

【1】Dijkstra's algorithm http://blog.csdn.net/lsxpu/article/details/41445299

【2】Prim算法与Dijkstra算法的区别 http://blog.csdn.net/superdiablo/article/details/6173001



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值