动态规划作业-多段图的最短路径问题

多段图的最短路径问题

问题:设图G=(V,E)是一个带权有向图,如果把顶点集合V划分成k个互不相交的子集Vi(2<=k<=n,1<=i<=k),

使得E中的任何一条边<u,v>,必有u∈Vi, v∈Vi+m(1<=i<k,1<i+m<=k),则称图G为多段图,称s∈V1为源点,

t∈Vk为终点。

多段图的最短路径问题为从源点到终点的最小代价路径。

子问题:设Cuv表示多段图的有向边<u,v>上的权值,将从源点s到终点t的最短路径长度即为d(s,t),

考虑原问题的部分解d(s,v),显然有下式成立

d(s,v)=Csu                                  (<s,v>∈E)

d(s,v)=min(d(s,u)+Cuv)            (<u,v>∈E)

算法:多段图的最短路径问题

输入:多段图的代价矩阵

输出:最短长度及路径c[n][n]

1.循环变量j从1~n-1重复下述操作,执行填表工作

1.1考察顶点j的所有入边,对于边<i,j>∈E,执行下述操作

1.1.1cost[j]=min{cost[i]+c[i][j]};

1.1.2path[j]=使cost[i]+c[i][j]最小的i;

1.2 j++;

2.输出最短路径长度cost[n-1];

3.循环变量i=path[n-1].循环直到path[i]=0,输出最短路径经过的顶点;

3.1 输出path[i];

3.2 i=path[i]

#include<iostream>
#include<algorithm>
#include<stdio.h>
#define Max 0xffff
using namespace std;
//动态规划求最短路径
void dp_path(int c[][100], int *cost, int *path) {
    int m, n;
    cout << "输入顶点个数和边个数" << endl;
    cin >> n >> m;
    //初始化代价矩阵
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            c[i][j] = Max;
    //输入代价矩阵
    int u, v, s;
    for (int i = 0; i < m; i++) {
        cin >> u >> v >> s;
        //cout<<u<<v<<s<<endl;
        c[u][v] = s;
    }
    for(int i=0;i<n;i++)
        cost[i]=Max;
    path[0] = -1;
    cost[0] = 0;
    for (int j = 1; j < n; j++) {
        for (int i = j-1; i >=0; i--) {
            if (cost[j] > cost[i] + c[i][j]) {
                path[j] = i;
                cost[j] = cost[i] + c[i][j];
            }
        }
    }
    cout<<cost[n-1]<<endl;
    int i=path[n-1];
    cout<<path[n-1]<<endl;
    while(path[i]>=0){
        cout<<path[i]<<endl;
        i=path[i];
    }
}
int main()
{
    int c[100][100], cost[100], path[100];
    dp_path(c, cost, path);
    getchar();
    return 0;
}

原文地址:https://www.cnblogs.com/zuoyou151/p/9028675.html

时间: 2024-08-02 14:34:50

动态规划作业-多段图的最短路径问题的相关文章

uva 116 Unidirectional TSP(动态规划,多段图上的最短路)

这道题目并不是很难理解,题目大意就是求从第一列到最后一列的一个字典序最小的最短路,要求不仅输出最短路长度,还要输出字典序最小的路径. 这道题可以利用动态规划求解.状态定义为: cost[i][j] = max{cost[i+1][j+k]+c[i][j]}(k=-1,0,1) 关于最短路长度的求法,我们可以通过上边的状态转移方程递推求解.cost代表从第i列到第c-1列的最短路,只要找出cost[0][j](j代表行号)中的最大值,我们得到的结果就是最短路. 我们已经得到了最短路的长度.下一步,

多段图动态规划dp

多段图问题是DP的基础题目.大体的意思是有一个赋权有向图,其顶点集被分为几个子集.求经过每个子集从源点到终点的最短路径 1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.Scanner; 4 import java.util.Stack; 5 6 public class Main { 7 private static final int k = 3; 8 private static int[

有向无环图的最短路径

我们已经知道了如何通过Dijkstra算法在非负权图中找到最短路径.即使图中有负权边,我们也知道通过Bellman-Ford算法找到一个从 给定的源点到其它所有节点的最短路径.现在我们将看到一个在线性时间内运行得更快的算法,它可以在有向无环图中找到从一个给定的源点到其它所有可达顶点的 最短路径,又名有向无环图(DAG). 由于有向无环图无环所以我们不必担心负环的问题.正如我们已经知道在负环里讨论最短路径是毫无意义的一样,因为我们可以在这些环里不断“循环”,但实际上我们得到的路径将变得越来越短(构

数据结构 -- 图的最短路径 Java版

作者版权所有,转载请注明出处,多谢.http://www.cnblogs.com/Henvealf/p/5574455.html 上一篇介绍了有关图的表示和遍历实现.数据结构 -- 简单图的实现与遍历 (Java)现在就来看看关于求图的最短路径的问题: 注意:本人学习图的时候看的书是: <<数据结构与算法 Java语言版>> (美)Adam Drozdek/著 周翔/译 机械工业出版社出版 由于要仔细讲解内容过多并且本人水平有限,推荐大家找出这本书来看,本篇文章主要是对其中Dijk

带权图的最短路径算法(Dijkstra)实现

一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带权的.不带权的Dijkstra算法要简单得多(可参考我的另一篇:无向图的最短路径算法JAVA实现):而对于带权的Dijkstra算法,最关键的是如何“更新邻接点的权值”.本文采用最小堆主辅助,以重新构造堆的方式实现更新邻接点权值. 对于图而言,存在有向图和无向图.本算法只需要修改一行代码,即可同时实

多段图

多段图问题是求由s到t的最小成本路径. 图中的结点被划分成 k≥ 2个不相交的集合Vi , 1≤i≤k,其中V1和Vk分别只有一个结点 s (源点) 和t ( 汇点). 多段图向前处理的算法 1.算法执行过程 COST[j]=c(j,r)+COST[r]; 第4段            COST(4,9) = c(9,12) = 4 COST(4,10) = c(10,12) = 2 COST(4,11) = c(11,12) = 5 第3段            COST(3,6) = min

贪心算法-图的最短路径算法Dijkstra之证明

一.问题:图的最短路径 定义图G=(V,E),而且每条边上的权值非负,求顶点s 到图中任意一点的最短距离.图中任意两点之间的距离定义为:路径上所有边的权值的和. 二.算法:Dijkstra算法 设S是探查的顶点的集合,对每个,我们存储一个距离d(u) 初始S={s},d(s)=0 While S != V 选择一个顶点使得从S到v至少有一条边并且 把v加入到S并且定义 End 三.证明算法的正确性: 只需证明,在算法执行中任意一点的集合S,对每个,路径是最短的s-u路径. 用数学归纳法证明算法的

图的最短路径和拓扑排序

图的最短路径 从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径 图的最短路径有许多重要的应用. 例如:上图中v0-v8有9个点,可以看做不同的地点,现在要规划出v0到其它某个点地点的最短路线规划 构建最短路径中比较常见的一种算法即为dijstra(迪杰斯特拉)算法 二.dijstra(迪杰斯特拉)算法 究竟什么是迪杰斯特拉算法?它是如何寻找图中顶点的最短路径呢? 这个算法的本质,是不断刷新起点与其他各个顶点之间的 “距离表”. 让我们来演示一下迪杰斯特拉

图的最短路径算法 Bellman-Ford算法

Bellman-Ford算法由美国数学家理查德•贝尔曼(Richard Bellman, 动态规划的提出者)和小莱斯特•福特(Lester Ford)发明. 适用范围:- 有向图,无向图(需把edge重复2遍): 即对于边w(u, v),存储2遍: w(u,v), w(v,u):- 适用于从图中某个固定点,到其他点的最短路径求解: 算法大致说明:1. 初始化所有点,用dis[i]数组存储root点到i点的最短路径:2. dis[root]为0,其他的dis[i]用最大值初始化:3. 遍历所有的边