prim最小生成树算法 邻接表+STL实现

一、预备知识

优先队列

二、代码:

#include<iostream>
#include<list>
#include<vector>
#include<map> 
#include<queue>

#define INF 9999999
using namespace std;

class Graph
{
	int n;
	list< pair<int,double> >*adj;	//邻接表 
public:
	Graph(int _n)
	{
		this->n = _n;
		adj = new list<pair<int,double> >[_n];
	}
	void addEdge(int u, int v, double weight)
	{
		adj[u].push_back(make_pair(v, weight));
		adj[v].push_back(make_pair(u, weight));
	}
	void primMST();
};
void Graph::primMST()
{
	//用优先队列当小根堆,pair排序时先按first升序排,相等再按second升序排
	//因要按weight来排序,所以把weight放前面
	priority_queue< pair<double,int>,
				   	vector<pair<double,int> >,
				   	greater<pair<double,int> > > pq;
		
	vector<int>key(n,INF);		//key[v]表示存放到顶点v的weight最小值 
	vector<int> parent(n,-1);	//parent[v] = u:u是已经在MST(最小生成树)的顶点,v不是,由u发现的v 
	vector<bool>inMST(n,false);	//记录顶点在不在MST里 
	
	int src=0;		//从0开始 
	key[src] = 0;	//到0的边的权值为0 
	pq.push(make_pair(0,src));//pair默认先以first升序后,相同再以second升序 
	while(!pq.empty())
	{
		int u = pq.top().second;
		pq.pop();
		
		inMST[u] = true;	//标记已经连好的那边了 
		
		list<pair<int,double> >::iterator it;
		for(it = adj[u].begin(); it != adj[u].end(); it++)
		{
			int v = (*it).first;		//or int v = it->first 
			double weight = (*it).second;
			
			if(inMST[v] == false && key[v] > weight)
			{  
				key[v] = weight;
				pq.push(make_pair(key[v],v));
				parent[v] = u;
			}			 
		} 
	} 
	for(int i = 1 ;i < n; i++)
	{
		cout<<parent[i]<<"->"<<i<<" weight is "<<key[i]<<endl;  
	}
}
int main() 
{ 
    int V = 9; 
    Graph g(V); 
    g.addEdge(0, 1, 4); 
    g.addEdge(0, 7, 8); 
    g.addEdge(1, 2, 8); 
    g.addEdge(1, 7, 11); 
    g.addEdge(2, 3, 7); 
    g.addEdge(2, 8, 2); 
    g.addEdge(2, 5, 4); 
    g.addEdge(3, 4, 9); 
    g.addEdge(3, 5, 14); 
    g.addEdge(4, 5, 10); 
    g.addEdge(5, 6, 2); 
    g.addEdge(6, 7, 1); 
    g.addEdge(6, 8, 6); 
    g.addEdge(7, 8, 7); 
  
    g.primMST(); 
  
    return 0; 
} 

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值