动态规划求多段图单源最短路径
从终点n-1开始,直到顶点0,对每个点:
遍历其所能达到的各个结点,判断通过该结点访问终点的路径是否小于当前能找到的最短距离,是则更新,否则不变。
最后,顶点0找到的最短距离必然是该点到达终点n-1的最短距离。
* 局限性:本程序只能求从顶点0到顶点n-1的最短路,且只能从编号较小的点访问编号较大的点。
-
#include<iostream>
-
using namespace std;
-
-
#define N 50 // 最多顶点数
-
#define MAX 9999 // 最大路径权
-
-
typedef struct NODE { // 顶点结构
-
int v; // 顶点的编号
-
int len; // 到顶点的距离
-
struct NODE *next; // 下一个可到达点
-
}Node;
-
-
int n; // 顶点数
-
Node node[N]; // 存储顶点到各点的距离
-
int route[N]; // 存放顶点到终点最短路的路径
-
-
/*
-
* 求多段图单源最短路径的DP解法
-
*
-
* 输入:n - 顶点数, mz[][] - 存放距离的邻接矩阵
-
* 输出:cost[0] - 最短路长度, route[] - 顶点到终点最短路的路径
-
*/
-
int dp(){
-
int cost[N], path[N];
-
int i;
-
-
/* 初始化距离 */
-
cost[n-1] = 0;
-
-
/* DP求解 */
-
for(i=n-2; i>=0; i--){
-
cost[i] = MAX; // 一开始不可到达
-
Node* p = node[i].next;
-
while(p){
-
if(cost[p->v] + p->len < cost[i]){ // 如果这个走法比之前的消耗更小则更新
-
cost[i] = cost[p->v] + p->len;
-
path[i] = p->v;
-
}
-
p = p->next;
-
}
-
}
-
-
/* 计算最短路径 */
-
i = 1;
-
route[0] = 0;
-
while(route[i-1]!=n-1){
-
route[i] = path[route[i-1]];
-
i++;
-
}
-
-
return cost[0];
-
}
-
-
-
int main(){
-
int i,j;
-
cin>>n;
-
-
/* 输入各个顶点所能到达的结点及对应权值(以0结束) */
-
for(i=0; i<n; i++){
-
Node* p;
-
while(cin>>j&&j!=0){
-
p = new Node;
-
p->v = j;
-
cin>>p->len;
-
p->next = node[i].next;
-
node[i].next = p;
-
}
-
}
-
-
cout<<"顶点0到顶点"<<n-1<<"的距离是:"<<dp()<<endl;
-
-
/* 打印最短路径 */
-
cout<<"最短路径是:";
-
for(i=0; route[i] != n-1; i++)cout<<route[i]<<"->";
-
cout<<n-1<<endl;
-
-
return 0;
-
}