从终点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;
- }