码迷,mamicode.com
首页 > 编程语言 > 详细

最短路问题 Dijkstra算法- 路径还原

时间:2020-02-16 20:59:47      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:ios   start   覆盖   printf   起点   最短路径   最短路问题   取出   无效   

  1 // 路径还原
  2 // 求最短路,并输出最短路径
  3 // 在单源最短路问题中我们很容易想到,既然有许多条最短路径,那将之都存储下来即可
  4 // 但再想一下,我们是否要把所有的最短路径都求出来呢?
  5 // 实际上不需要,这里我们用一个数组来记录最短路径,之后的最短路径都是在之前最短路径上的延申
  6 // 所以只需要一个数组,存储前一个节点即可
  7 
  8 // 这里我们用邻接表和优先级队列来实现复杂度为o( E*log(N) )的Dijkstra算法
  9 
 10 #include <cstdio>
 11 #include <iostream>
 12 #include <queue>
 13 #include <vector>
 14 
 15 using namespace std;
 16 
 17 const int max_N = 1000+2;
 18 const int max_E = 10000+2;
 19 const int INF = 1e9;
 20 
 21 int N,E,S;
 22 int d[max_N];
 23 int pre[max_N];
 24 
 25 struct edge
 26 {
 27     int to,cost;
 28 };
 29 edge es[max_N];
 30 
 31 vector<edge> G[max_N];
 32 
 33 typedef pair<int,int> P;
 34 
 35 void Dijkstra(int s)
 36 {
 37     pre[s]=-1;
 38     fill(d,d+N,INF);
 39     d[s]=0;
 40     // 实现最小堆
 41     priority_queue< P,vector<P>,greater<P> > que;
 42     que.push(P(0,s));
 43 
 44     while(!que.empty())
 45     {
 46         // 非空时,取出一个顶点
 47         P p=que.top();
 48         que.pop();
 49         // 当前节点的编号是v,队列中记录的到当前节点的最短距离是p.first
 50         int v=p.second;
 51         // 如果当前节点的最小值,小于数组中记录的最小值的话
 52         // 说明当前节点的最小值已经被覆盖过了,这个节点是无效节点,继续下一次循环
 53         if(d[v]<p.first)
 54         {
 55             continue;
 56         }
 57 
 58         for(int i=0;i<G[v].size();++i)
 59         {
 60             edge e=G[v][i];
 61 
 62             if(d[e.to]>d[v] + e.cost)
 63             {
 64                 d[e.to]=d[v]+e.cost;
 65                 pre[e.to]=v;
 66                 que.push(P( d[e.to],e.to ));
 67             }
 68         }
 69 
 70     }
 71 
 72 }
 73 
 74 void path(int i)
 75 {
 76     if(i==S)
 77     {
 78         printf("start:%d\n",S);
 79         return;
 80     }
 81     vector<int> p;
 82     for(;i!=-1;i=pre[i])
 83     {
 84         p.push_back(i);
 85     }
 86     vector<int>::iterator it;
 87     for(it=p.end()-1;it!=p.begin()-1;--it)
 88     {
 89         cout<<*it<< ;
 90     }
 91     cout<<endl;
 92 }
 93 
 94 int main()
 95 {
 96     scanf("%d %d",&N,&E);
 97     int a,b,c;
 98     for(int i=0;i<E;++i)
 99     {
100         scanf("%d %d %d",&a,&b,&c);
101         edge e;
102         e.to=b;
103         e.cost=c;
104         G[a].push_back(e);
105         // 无向图
106         e.to=a;
107         e.cost=c;
108         G[b].push_back(e);
109     }
110     // 起点为0号节点
111     S=0;
112 
113     Dijkstra(S);
114 
115     for(int i=0;i<N;++i)
116     {
117         printf("%d ",d[i]);
118     }
119 
120     printf("\n\n");
121 
122     for(int i=0;i<N;++i)
123     {
124         path(i);
125     }
126 
127     return 0;
128 }
129 
130 /*
131 7 10
132 0 1 2
133 0 2 5
134 1 2 4
135 1 3 6
136 1 4 10
137 2 3 2
138 3 5 1
139 4 5 3
140 4 6 5
141 5 6 9
142 
143 */

 

最短路问题 Dijkstra算法- 路径还原

标签:ios   start   覆盖   printf   起点   最短路径   最短路问题   取出   无效   

原文地址:https://www.cnblogs.com/jishuren/p/12318415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!