有代价的单源最短路径
2016-04-05 13:47 GarfieldEr007 阅读(648) 评论(0) 编辑 收藏 举报问题:有代价的单源最短路径,并要求存储路径。(求最短的路径,并使代价最小)
特点:
* 存储路径:决定了难以用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:
- #include<iostream>
- #include<memory.h>
- #include<vector>
- using namespace std;
- #define N 505
- int map[N][N];
- vector<int> path,min_path;
- int bike[N];
- bool visit[N];
- #define INF 10000000
- int dest,n,req;//req:require
- int min_d,min_bring,min_back;
- int cur_d,cur_bring,cur_back;
- void dfs(int p)
- {
- int i;
- if(p==dest)
- {
- if(cur_d<min_d ||
- cur_d==min_d && cur_bring < min_bring||
- cur_d == min_d && cur_bring == min_bring && cur_back<min_back)
- {
- min_d = cur_d;
- min_bring = cur_bring;
- min_back = cur_back;
- min_path = path;
- }
- return;
- }
- else
- {
- for(i=0;i<=n;i++)
- {
- if(!visit[i]&&map[p][i]!=INF)
- {
- cur_d += map[p][i];
- visit[i] = true;
- path.push_back(i);
- if(bike[i]<req)
- {
- if(cur_back >= req-bike[i])
- {
- cur_back -= (req-bike[i]);
- dfs(i);
- cur_back += (req-bike[i]);
- }
- else
- {
- int t = cur_back;
- cur_bring += req-bike[i] - cur_back;
- cur_back = 0;
- dfs(i);
- cur_back = t;
- cur_bring -= req-bike[i] - cur_back;
- }
- }
- else
- {
- cur_back += bike[i]-req;
- dfs(i);
- cur_back -= (bike[i]-req);
- }
- path.pop_back();
- visit[i] = false;
- cur_d-=map[p][i];
- }
- }
- }
- }
- int main()
- {
- int cm,m,i,j,t,a,b;
- scanf("%d%d%d%d",&cm,&n,&dest,&m);
- req = cm/2;
- for(i=0;i<n;i++)
- scanf("%d",&bike[i+1]);
- memset(visit,false,sizeof(visit));
- visit[0] = true;
- for(i=0;i<=n;i++)
- for(j=0;j<=n;j++)
- map[i][j] = INF;
- for(i=0;i<m;i++)
- {
- scanf("%d%d%d",&a,&b,&t);
- if(map[a][b]>t)
- map[a][b] = map[b][a] = t;
- }
- min_d = min_bring = min_back = INF;
- cur_d = cur_bring = cur_back = 0;
- path.push_back(0);
- dfs(0);
- cout<<min_bring<<" ";
- printf("%d",min_path[0]);
- for(i=1;i<min_path.size();i++)
- printf("->%d",min_path[i]);
- cout<<" "<<min_back<<endl;
- return 0;
- }
from: http://blog.csdn.net/abcjennifer/article/details/19830187