有代价的单源最短路径

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有代价的单源最短路径相关的知识,希望对你有一定的参考价值。

问题:有代价的单源最短路径,并要求存储路径。(求最短的路径,并使代价最小)

特点:

* 存储路径:决定了难以用dijkstra,可以用flody,用path[i][j]表示 i 想走到 j 迈出的第一步。假设k是 i->j 的中间节点,更新时候用path[i][j] = path[i][k],具体做法见link。但是flody比较耗时(O(N^3))

* 有代价:如果想用flody的话,有要求代价最小,就需要将最短路相等的都记录下来。边一多代价更上去了。所以还是dfs比较方便。

 

例题:

PAT 1018(http://pat.zju.edu.cn/contests/pat-a-practise/1018)

 

这道题关键要想到用dfs,就好做了。Code:

 

 

[cpp] view plain copy
 
 技术分享技术分享
  1. #include<iostream>  
  2. #include<memory.h>  
  3. #include<vector>  
  4. using namespace std;  
  5. #define N 505  
  6. int map[N][N];  
  7. vector<int> path,min_path;  
  8. int bike[N];  
  9. bool visit[N];  
  10. #define INF 10000000  
  11. int dest,n,req;//req:require  
  12. int min_d,min_bring,min_back;  
  13. int cur_d,cur_bring,cur_back;  
  14.   
  15. void dfs(int p)  
  16. {  
  17.     int i;  
  18.     if(p==dest)  
  19.     {  
  20.         if(cur_d<min_d ||  
  21.             cur_d==min_d && cur_bring < min_bring||  
  22.             cur_d == min_d && cur_bring == min_bring && cur_back<min_back)  
  23.         {  
  24.             min_d = cur_d;  
  25.             min_bring = cur_bring;  
  26.             min_back = cur_back;  
  27.             min_path = path;  
  28.         }  
  29.         return;  
  30.     }  
  31.     else  
  32.     {  
  33.         for(i=0;i<=n;i++)  
  34.         {  
  35.             if(!visit[i]&&map[p][i]!=INF)  
  36.             {  
  37.                 cur_d += map[p][i];  
  38.                 visit[i] = true;  
  39.                 path.push_back(i);  
  40.                 if(bike[i]<req)  
  41.                 {  
  42.                     if(cur_back >= req-bike[i])  
  43.                     {  
  44.                         cur_back -= (req-bike[i]);  
  45.                         dfs(i);  
  46.                         cur_back += (req-bike[i]);  
  47.                     }  
  48.                     else  
  49.                     {  
  50.                         int t = cur_back;  
  51.                         cur_bring += req-bike[i] - cur_back;  
  52.                         cur_back = 0;  
  53.                         dfs(i);  
  54.                         cur_back = t;  
  55.                         cur_bring -= req-bike[i] - cur_back;  
  56.                     }  
  57.                 }  
  58.                 else  
  59.                 {  
  60.                     cur_back += bike[i]-req;  
  61.                     dfs(i);  
  62.                     cur_back -= (bike[i]-req);  
  63.                 }                 
  64.                 path.pop_back();  
  65.                 visit[i] = false;  
  66.                 cur_d-=map[p][i];  
  67.             }  
  68.         }  
  69.     }  
  70. }  
  71.   
  72. int main()  
  73. {  
  74.     int cm,m,i,j,t,a,b;  
  75.     scanf("%d%d%d%d",&cm,&n,&dest,&m);  
  76.     req = cm/2;  
  77.     for(i=0;i<n;i++)  
  78.         scanf("%d",&bike[i+1]);  
  79.     memset(visit,false,sizeof(visit));  
  80.     visit[0] = true;  
  81.   
  82.     for(i=0;i<=n;i++)  
  83.         for(j=0;j<=n;j++)  
  84.             map[i][j] = INF;  
  85.   
  86.     for(i=0;i<m;i++)  
  87.     {  
  88.         scanf("%d%d%d",&a,&b,&t);  
  89.         if(map[a][b]>t)  
  90.             map[a][b] = map[b][a] = t;  
  91.     }  
  92.     min_d = min_bring = min_back = INF;  
  93.     cur_d = cur_bring = cur_back = 0;  
  94.     path.push_back(0);  
  95.     dfs(0);  
  96.     cout<<min_bring<<" ";  
  97.     printf("%d",min_path[0]);  
  98.     for(i=1;i<min_path.size();i++)  
  99.         printf("->%d",min_path[i]);  
  100.     cout<<" "<<min_back<<endl;  
  101.     return 0;  
  102. }  

from: http://blog.csdn.net/abcjennifer/article/details/19830187

以上是关于有代价的单源最短路径的主要内容,如果未能解决你的问题,请参考以下文章

用小根堆实现dijkstra,求图的单源最短路径

探秘SPFA——强大的单源最短路径算法

Dijkstra 的单源最短路径,带有额外的边,权重为“w”

Dijkstra 的单源最短路径算法能否检测到图中的无限循环?

贪心算法—单源最短路径

数据结构求图的单源最短路径