zoukankan      html  css  js  c++  java
  • 最短路问题 Dijkstra算法- 路径还原

      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
    ",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("
    
    ");
    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 */
  • 相关阅读:
    .NET的JSNO 序列化跟反序列化
    SQL Server 查询分析器提供的所有键盘快捷方式(转)
    SQL Server 中WITH (NOLOCK)浅析(转潇湘隐者)
    Microsoft Dynamics CRM 2011的组织服务中的RetrieveMultiple方法(转)
    C#对多个集合和数组的操作(合并,去重,判断)
    Silverlight Telerik控件学习:主题Theme切换html教程
    VMware 11安装Mac OS X 10.10
    Android 下载网络图片注意的问题
    对下载文件是否完整的判断方法
    Android实现通用的ActivityGroup(效果类似Android微博客户端主界面),强烈建议不要再使用TabActivity
  • 原文地址:https://www.cnblogs.com/jishuren/p/12318415.html
Copyright © 2011-2022 走看看