Bellman Ford+SPFA队列优化(路径还原 输出最短路的路径)
来源:互联网 发布:手机网络信息怎么收费 编辑:程序博客网 时间:2024/05/06 06:24
——————有向图——————
①邻接表(效率较高)
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>using namespace std;#define INF 0xfffffff#define MAXN 1010struct Edge{ int u,v,w;};Edge edge[MAXN];//邻接表int n,m;//顶点数和边数int dist[MAXN];//顶点s到其他顶点的最短路径、int path[MAXN];//path[i]表示v0到vi的最短路径上vi的前一个顶点的序号int shortest[MAXN];//输出最短路径上的各个顶点时存放的各个顶点的序号void Bellman(int s)//顶点s到其他顶点的最短路径{ int i,j; for(i=0; i<n; ++i)//初始化 { dist[i]=INF; path[i]=-1; } dist[s]=0; for(i=1; i<n; ++i) for(j=0; j<m; ++j) { Edge e=edge[j]; if(dist[e.u]!=INF&&e.w+dist[e.u]<dist[e.v])//顶点k到j有直接路径而且途径k可以使得路径缩短 { dist[e.v]=e.w+dist[e.u]; path[e.v]=e.u; } }}int main(){ ios::sync_with_stdio(false); cin.tie(0); int i,j; cin>>n>>m; for(i=0; i<m; ++i) cin>>edge[i].u>>edge[i].v>>edge[i].w; Bellman(0);//顶点0到其他顶点的最短路 for(i=1; i<n; ++i)//依次输出每个顶点最短路的路径节点 { cout<<dist[i]<<'\t';//最短路 memset(shortest,0,sizeof(shortest)); int k=0; shortest[k]=i; while(path[shortest[k]]!=0)//倒向追踪 { ++k; shortest[k]=path[shortest[k-1]]; } ++k; shortest[k]=0; for(j=k; j>0; --j)//路径输出 cout<<shortest[j]<<"→"; cout<<shortest[0]<<endl; } return 0;}/**7 100 1 60 2 50 3 51 4 -12 1 -22 4 13 2 -23 5 -14 6 35 6 3**/
②邻接矩阵
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <map>#include <algorithm>using namespace std;#define INF 0xfffffff#define MAXN 1010int n,m;//顶点数和边数int edge[MAXN][MAXN];//邻接矩阵int dist[MAXN];//顶点s到其他顶点的最短路径、int path[MAXN];//path[i]表示v0到vi的最短路径上vi的前一个顶点的序号int shortest[MAXN];//输出最短路径上的各个顶点时存放的各个顶点的序号void Bellman(int s)//顶点s到其他顶点的最短路径{ int i,j,k; for(i=0; i<n; ++i)//初始化 { dist[i]=edge[s][i]; if(i!=s&&dist[i]<INF) path[i]=s; else path[i]=-1; } for(i=2; i<n; ++i) for(j=0; j<n; ++j) if(j!=s) { for(k=0; k<n; ++k) if(edge[k][j]<INF&&dist[k]+edge[k][j]<dist[j])//顶点k到j有直接路径而且途径k可以使得路径缩短 { dist[j]=dist[k]+edge[k][j]; path[j]=k; } }}int main(){ ios::sync_with_stdio(false); cin.tie(0); int i,j,u,v,w; cin>>n>>m; for(i=0; i<n; ++i)//初始化 for(j=0; j<n; ++j) { if(i==j) edge[i][j]=0; else edge[i][j]=INF; } for(i=0; i<m; ++i) { cin>>u>>v>>w; edge[u][v]=w; } Bellman(0);//顶点0到其他顶点的最短路 for(i=1; i<n; ++i)//依次输出每个顶点最短路的路径节点 { cout<<dist[i]<<'\t';//最短路 memset(shortest,0,sizeof(shortest)); int k=0; shortest[k]=i; while(path[shortest[k]]!=0)//倒向追踪 { ++k; shortest[k]=path[shortest[k-1]]; } ++k; shortest[k]=0; for(j=k; j>0; --j)//路径输出 cout<<shortest[j]<<"→"; cout<<shortest[0]<<endl; } return 0;}/**7 100 1 60 2 50 3 51 4 -12 1 -22 4 13 2 -23 5 -14 6 35 6 3**/
③SPFA队列优化
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <queue>#include <iomanip>#include <algorithm>#define MAXN 10010#define INF 0xfffffffusing namespace std;struct ArcNode{ int to; int weight; ArcNode *next;};queue<int> Q;//队列中的节点为顶点序号int n;//顶点个数ArcNode * List[MAXN];//每个顶点的边链表表头指针int inq[MAXN];//每个顶点是否在队列中的标志int dist[MAXN],path[MAXN];void SPFA(int src){ int i,u;//u为队列头顶点序号 ArcNode * temp; for(i=0; i<n; ++i)//初始化 { dist[i]=INF; path[i]=src; inq[i]=0; } dist[src]=0; path[i]=src; ++inq[src]; Q.push(src); while(!Q.empty()) { u=Q.front(); Q.pop(); --inq[u]; temp=List[u]; while(temp!=NULL) { int v=temp->to; if(dist[v]>dist[u]+temp->weight) { dist[v]=dist[u]+temp->weight; path[v]=u; if(!inq[v]) { Q.push(v); ++inq[v]; } temp=temp->next; } } }}int main(){ int i,j; int u,v,w; cin>>n; memset(List,0,sizeof(List)); ArcNode *temp; while(cin>>u>>v>>w) { temp=new ArcNode; temp->to=v;//构造邻接表 temp->weight=w; temp->next=NULL; if(List[u]==NULL) List[u]=temp; else { temp->next=List[u]; List[u]=temp; } } SPFA(0);//求顶点0到其他顶点的最短路径 for(j=0; j<n; ++j)//释放边链表上各边结点所占用的存储空间 { temp=List[j]; while(temp!=NULL) { List[j]=temp->next; delete temp; temp=List[j]; } } int shortest[MAXN];//输出最短路径上的各个顶点时存放各个顶点的序号 for(i=1; i<n; ++i) { cout<<dist[i]<<'\t';//输出顶点0到顶点i的最短路径长度 memset(shortest,0,sizeof(shortest)); int k=0; shortest[k]=i; while(path[shortest[k]]!=0) { ++k; shortest[k]=path[shortest[k-1]]; } ++k; shortest[k]=0; for(j=k; j>0; --j) cout<<shortest[j]<<"->"; cout<<shortest[0]<<endl; } return 0;}/*70 1 60 2 50 3 51 4 -12 1 -22 4 13 2 -23 5 -14 6 35 6 3*/
0 0
- Bellman Ford+SPFA队列优化(路径还原 输出最短路的路径)
- 单点最短路径算法 bellman-ford模板和队列优化后的spfa算法模板
- 最短路 SPFA (对于bellman-ford 的优化)
- 总结一下最短路径的贝尔曼-福特算法(Bellman-Ford)及用队列优化(spfa)
- 总结一下最短路径的贝尔曼-福特算法(Bellman-Ford)及用队列优化(spfa)
- 最短路模板-folyd bellman Dijkastra+路径还原+SPFA
- 最短路径(四)—Bellman-Ford的队列优化(邻接表)
- 从零开始学算法(八)最短路径之Bellman-Ford算法的队列优化以及几种最短路径算法对比
- 单源最短路之spfa算法代码(bellman-ford算法的队列优化)
- SPFA(bellman-ford的队列优化)
- spfa--Bellman-Ford的队列优化
- 单源最短路径算法 Bellman-Ford && SPFA 及 最短路算法统一归纳
- 单源最短路径算法 Bellman-Ford && SPFA 及 最短路算法统一归纳
- 负权边的最短路径--Bellman-Ford算法及其优化
- Bellman-Ford算法和队列优化(SPFA)——求单源最短路径
- 四、最短路径之Bellman-Ford与SPFA
- [图论] 最短路径(Bellman-Ford , SPFA , Floyed , Dijkstra)
- [图论] 最短路径(Bellman-Ford , SPFA , Floyed , Dijkstra)
- Kubernetes1.3:QoS服务质量管理
- Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)
- ZYNQ部分功能引脚定义
- Spring 注解的方式进行事务管理
- 关于java集合类
- Bellman Ford+SPFA队列优化(路径还原 输出最短路的路径)
- POJ 1185 - 炮兵阵地
- libevent的evbuffer跟bufferevent的区别
- 使用Session验证用户登录
- pyqt 弹出对话框
- 三种方式实现二维码(java)
- Work<hdoj5326>
- HDOJ-1878 欧拉回路
- 从零学React Native之02状态机