这里给出了 Bellmanford 和 SPFA 的算法思想和伪代码, 但这离具体的实现还有差距, 最短路径算法的使用频率很高, 有必要总结一下
1. SPFA 算法
算法的核心是: 松弛有效的操作必然发生在松弛前导节点成功松弛的节点上
/* * spfa.h * * Created on: Apr 8, 2014 * Author: sangs */ #ifndef SPFA_H_ #define SPFA_H_ #include <queue> using namespace std; extern class Edge; const int MAXNUM = 1000; int dist[MAXNUM]; int father[MAXNUM]; int mark[MAXNUM]; vector<Edge> graph[MAXNUM]; void spfa(int st, int ed) { queue<int> record; record.push(st); dist[st] = 0; father[st] = -1; while(!record.empty()) { int u = record.front().index; record.pop(); for(int i = 0; i < graph[u].size(); i ++) { int v = graph[u][i].index; if(dist[u] + graph[u][i].cost < dist[v]) { record.push(v); father[v] = u; dist[v] = dist[u] + graph[u][i].cost; } } } for(int i = ed; i != -1; i = father[i]) { mark[i] = 1; } } #endif /* SPFA_H_ */
2. Dijkstra 算法
代码的核心是对 visited 赋值在外面, 这样能够保证 st->ed 的路径是最短的
/* * Dijkstra.h * * Created on: Apr 8, 2014 * Author: sangs */ #ifndef DIJKSTRA_H_ #define DIJKSTRA_H_ extern class Node; const int MAXNUM = 1000; bool visited[MAXNUM]; /* * Always used to calculate the shortest path/length to specific node */ void dijkstra(int st, int ed) { priority_queue<int> record; record.push(st); while(!record.empty()) { int u = record.top(); while(!record.empty()) { Node v = record.top(); record.pop(); visited[v.index] = true; if(v == ed) { break; } for(int i = 0; i < graph[v.index].size(); i ++) { if(visited(...)) continue; record.push_back(Node(...)); } } } } #endif /* DIJKSTRA_H_ */
2014年4月18日21:51:42
上面的 SPFA 代码有误, 需要判断一个点是否两次被加入队列