[C++]C++ STL Dijkstra算法 存储多条相同最短路径 shortest path
来源:互联网 发布:田丰 阿里云 编辑:程序博客网 时间:2024/06/04 19:30
Dijkstra存储多条相同最短路径
使用list结构存储多个顶点(预备)
完整源码
#include <iostream>#include <list>using namespace std;int main(){ list<int> larray[100]; larray[0].push_back(0); larray[0].push_back(1); larray[1].push_back(10); larray[1].push_back(20); larray[1].push_back(30); for(int i = 0 ; i <= 1; i++) { list<int> mylist = larray[i]; for(list<int>::iterator ii = mylist.begin(); ii != mylist.end(); ii++) cout << *ii << " "; cout << endl; }}
测试运行
0 110 20 30
代码说明
- 这里把list数组的创建、添加、访问数据的方法先特别摘出来,是为了等下拼到原始的
Dijkstra算法
代码中保持头脑清晰; - 原始的
Dijstra算法
计算最短路径问题,只存储一条路径的实现(点我),也可见引用资料[0];
Dijkstra算法计算、存储多条最短路径(正题)
完整源码
#include <iostream>#include <vector>#include <tuple>#include <queue>#include <stack>#include <map>#include <list>using namespace std;double distTo[100];//int edgeTo[100]; list<int> edgeTo[100];int V, E;const double INF_MAX = 9999999.9;map<int , vector<tuple<int, int, double>>> EWD;stack<int> path;int coutSP = -1;struct GreaterThanByDist{ bool operator()(const int i, const int j) const { return distTo[i] > distTo[j]; }};priority_queue<int, vector<int>, GreaterThanByDist> Minpq;void relax(tuple<int, int, double> edge) { int v = get<0>(edge); int w = get<1>(edge); double weight = get<2>(edge); if (distTo[w] > distTo[v] + weight) { distTo[w] = distTo[v] + weight; //edgeTo[w] = v; edgeTo[w].clear(); edgeTo[w].push_back(v); Minpq.push(w); } else if(distTo[w] == distTo[v] + weight) { edgeTo[w].push_back(v); } }void DijkstraSP(int s,int V){ for(int v = 0 ; v < V; v++) distTo[v] = INF_MAX; distTo[s] = 0.0; Minpq.push(s); while(!Minpq.empty()) { int v = Minpq.top(); Minpq.pop(); for(vector<tuple<int, int, double>>::iterator ii = EWD[v].begin(); ii != EWD[v].end(); ii++) { relax(*ii); } } }void dfs(int source, int vertex){ coutSP++; if(vertex == source) coutSP = 0; for(list<int>::iterator ii = edgeTo[vertex].begin(); ii != edgeTo[vertex].end(); ii++) { if(coutSP == 0) path.push(vertex); path.push(*ii); dfs(source, *ii); }}void computeSP(int source, int vertex){ cout << "shortest path : "; DijkstraSP(source, V); cout << source << " to " << vertex << " ( " << distTo[vertex] << " ) " << " : " ; dfs(source , vertex); while(!path.empty()) { cout << path.top() << " "; path.pop(); } cout << endl;}void showEWD() { cout << "EdgeWeightedDigraph : " << endl; for(int v = 0; v < V; v++) { cout << v << " : "; for(vector<tuple<int, int, double>>::iterator ii = EWD[v].begin(); ii != EWD[v].end(); ii++) { cout << get<0>(*ii) << "->" << get<1>(*ii) << " " << get<2>(*ii) << " "; } cout << endl; }}int main(){ cin >> V >> E; for(int i = 0 ; i < E ;i++) { int v, w; double weight; cin >> v >> w >> weight; EWD[v].push_back(make_tuple(v, w, weight)); } //showEWD(); int source, vertex; cout << "source : "; cin >> source; cout << "vertex : "; cin >> vertex; computeSP(source, vertex); system("pause");}
模拟数据
测试运行
9110 1 0.10 2 0.10 3 0.11 4 0.11 5 0.12 6 0.13 7 0.14 8 0.15 8 0.16 8 0.17 8 0.1source : 0vertex : 8shortest path : 0 to 8 ( 0.3 ) : 0 1 5 8 0 3 7 8 0 2 6 8 0 1 4 8
详细说明
引入的标准
#include <list>
存储多个顶点
void relax(tuple<int, int, double> edge) { int v = get<0>(edge); int w = get<1>(edge); double weight = get<2>(edge); if (distTo[w] > distTo[v] + weight) { distTo[w] = distTo[v] + weight; //edgeTo[w] = v; edgeTo[w].clear(); edgeTo[w].push_back(v); Minpq.push(w); } else if(distTo[w] == distTo[v] + weight) { edgeTo[w].push_back(v); } }
- 每次遇到 更短 的最短路径,要清空
list
,使用这条语句edgeTo[w].clear();
; - 如果遇到 相同 的最短路径,只需要把顶点加入到
list
即可,else if {}
是新增的;
DFS遍历多条路径
int coutSP = -1;void dfs(int source, int vertex){ coutSP++; if(vertex == source) coutSP = 0; for(list<int>::iterator ii = edgeTo[vertex].begin(); ii != edgeTo[vertex].end(); ii++) { if(coutSP == 0) path.push(vertex); path.push(*ii); dfs(source, *ii); }}
- 变量
coutSP
的作用是一个flag
,告诉自己一条最短路径已经遍历完毕(回到了source
); - 预期输出的是一条完整的最短路径,比如从起点0一直-> -> ->到终点8,所以本质上终点8有必要在每次进入到新的一条最短路径的遍历时都再被插入(到path)一次,结合变量
coutSP
就可以做到了;
关于选择list的原因
list
起到的就是一个存储多个顶点的作用,C++ STL
的模板如此丰富,用stack
啊,queue
啊,甚至vector
还有map
都可以实现这个,选list
,只是为了和代码中已经用到的vector
以及map
做个区分,以为我用map vector
以及tuple
做了邻接表表示法的带权有向图。如果不需要保存多条最短路径,删代码的时候就很好删除了。
关于数据的输出效果
实际上,代码运行输出的结果会是一行的0 1 5 8 0 3 7 8 0 2 6 8 0 1 4 8
,上面为了看上去效果好一点,自己做了换行,实际上我把全部的路径都压到一个stack
里面,如果需要代码实际输出效果更好看,根据输出的内容来改就好,比如遇到起点source
的时候加个flag(打开)
,遇到终点8
让flag(关闭)
,这时候在输出一个换行什么的,因为和本文的主要内容不太相关,这里就略过。
引用资料
[0] [C++]C++ STL Dijkstra算法 带权有向图(邻接表)单源最短路径求解
http://blog.csdn.net/cook2eat/article/details/53912885[1]C++ STL
list begin()
http://www.cplusplus.com/reference/list/list/begin/list push_back()
http://www.cplusplus.com/reference/list/list/push_back/list clear()
http://www.cplusplus.com/reference/list/list/clear/
0 0
- [C++]C++ STL Dijkstra算法 存储多条相同最短路径 shortest path
- 最短路径图算法(shortest path dijkstra)
- 最短路径(SPF - Shortest Path Firsh) - Dijkstra算法
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现(C/C++)
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现(C/C++)
- 【Python排序搜索基本算法】之Dijkstra最短路径算法(Dijkstra's Shortest-Path Algorithm)
- dijkstra最短路径算法C实现
- GeeksForGeeks-Dijkstra’s shortest path algorithm最短路径
- Algorithms Part 1-Question 5- Dijkstra's shortest-path-最短路径算法
- 两点之间最短路径算法(Single-Dijkstra-shortest path)
- 图论:最短路径搜索--Dijkstra算法(c代码实现)
- 图论:最短路径搜索--Dijkstra算法(c代码实现)
- 最短路径之dijkstra算法的C语言实现
- 图论:最短路径搜索--Dijkstra算法(c代码实现)
- 最短路径Dijkstra算法的C语言实现
- 最短路径之Dijkstra算法 C语言实现
- C语言实现图的最短路径Dijkstra算法
- 最短路径—Dijkstra算法(C#)
- 网站后台改版,迁移老网站中Access数据库中新闻到新网站的方法
- 使用hibernate往mysql数据库插入数据中文乱码问题
- 安卓复习之旅—观察者模式
- android开发如何让声音从耳机和扬声器同时输出
- dorado7时间格式调整
- [C++]C++ STL Dijkstra算法 存储多条相同最短路径 shortest path
- 异步加载js 和 js时间线介绍
- 跟着斯坦福白胡子老头学UIDynamic动画的技巧
- 自定义实现微信通讯录效果View
- C++ STL template 重要吗?
- Struts2中的责任链模式模拟
- [CodeForces-325D] [Problem E]Reclamation
- Dalvik虚拟机进阶
- android studio 2.2.3使用讯飞sdk