300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > dijkstra--非负权值的单源最短路径STL实现(邻接表+优先队列) (带路径)

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

时间:2023-04-01 15:54:53

相关推荐

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

一、预备知识:

用优先队列做大小根堆

注意:是非负权值的单源最短路径的STL实现,权值是负的不能用dijkstra算法

解释在第一段

二、代码:

#include<iostream>#include<cstdio>#include<list>#include<queue>#include<set>#define INF 9999999using 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到vvector<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; }

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。