欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

dijkstra--非负权值的单源最短路径STL实现(邻接表+优先队列) (带路径)

程序员文章站 2022-04-06 15:08:01
...

一、预备知识:

用优先队列做大小根堆

注意:是非负权值的单源最短路径的STL实现,权值是负的不能用dijkstra算法
dijkstra--非负权值的单源最短路径STL实现(邻接表+优先队列) (带路径)
解释在第一段

二、代码:

#include<iostream>
#include<cstdio>
#include<list>
#include<queue>
#include<set>
#define INF 9999999

using namespace std;

class Graph
{
	int n;
	list<pair<int,double> > *adj;//邻接表 
public:
	Graph(int _n)
	{
		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)); 
	}
	void shortestPath(int src); 
};  
void Graph::shortestPath(int src)
{
	//用优先队列当小根堆,pair排序时先按first升序排,相等再按second升序排
	//因要按weight来排序,所以把weight放前面
	priority_queue< pair<double,int>,
				   	vector<pair<double,int> >,
				   	greater<pair<double,int> > > pq;  
				   
	vector<double>dist(n,INF);
	vector<int>parent(n,-1);	//parent[v] = u,由u到v
	vector<double>weights(n,INF);//weights[v]记录从src到v分支上某点到v的最小权值 
	pq.push(make_pair(0,src));
	dist[src] = 0;
	parent[src] = 0;
	weights[src] = 0;
	while(!pq.empty())
	{
		int u = pq.top().second;
		pq.pop();
		
		list<pair<int,double> >::iterator it;
		for(it = adj[u].begin(); it != adj[u].end(); it++)
		{
			int v = it->first;			 //获取顶点 
			double weight = it->second;	 //获取weight 
			
			if(dist[v] > dist[u]+weight)    
			{
				dist[v] = dist[u] + weight;
				pq.push(make_pair(dist[v],v));
				parent[v] = u;			//记录从哪到v最短 
				weights[v] = weight;	//记录到v的那条路径的路径 
			}
		}
	} 

	for(int i = 0 ;i < n; i++)
	{
		cout<<parent[i]<<"->"<<i<<" dist["<<i<<"]: "<<dist[i]
			<<" \t the weight "<<"from "<<parent[i]<<" to "<<i<<" is "<<weights[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.shortestPath(0); 
  
    return 0; 
} 

dijkstra--非负权值的单源最短路径STL实现(邻接表+优先队列) (带路径)


注:事实上路径已经用双亲表示的树(parent数组)表示了,所以想要打印出树来也是可以的

相关标签: dijkstra