847. Shortest Path Visiting All Nodes(三)
DP
这道题目还可以用动态规划解决。在图论中解决最短路径问题有Dijkstra算法和bellman-ford算法。这道题目也需要用到DP。所以先学习一下这两个算法的思想和区别。
两个算法比较
Dijstra算法用来解决单源最短路径问题。具体内容看[文章]
算法 | 解决问题 | 适用范围 | 解决思路 | 松弛对象 |
---|---|---|---|---|
Dijkstra算法 | 单源最短路径 | 权重是正的图 | 贪心 | 顶点 |
bellman-ford算法 | 单源最短路径 | 图,不可以有负权环路 | 动态规划 | 边 |
ps:虽然我也不明白为什么叫松弛。只知道是不断处理,不断优化的对象。
之所以做比较是想明白这两个算法有什么区别。以及第二个算法的思想是怎么应用在本题目。
本题目的DP方案参考链接。
首先使用Floy算法计算任意两点之间的最短路径。接着使用递归方程dp[i][j] = Math.min(dp[i][j],dp[包含u但是不包含v 的状态][u]+dist[u][v])。
public class ShortestPathVisitingAllNodesDP {private int[][] dis = new int[15][15];private int[][] dp =new int[1<<13][13];public int shortestPathLength(int[][] graph) {int N = graph.length;for (int[] row: dis) Arrays.fill(row, N*N);for (int i=0; i<N; i++) {for (int j=0; j<graph[i].length; j++) {int u = i, v = graph[i][j];dis[u][v] = 1;}}floyd(N);return dp(N);}/*** Floy算法:任意两点之间的最短距离* @param n*/public void floyd(int n) {for(int k=0; k<n; k++)for(int i=0; i<n; i++)for(int j=0; j<n; j++)dis[i][j] = Math.min(dis[i][j], dis[i][k]+dis[k][j]);}private int dp(int n) {for (int[] row: dp) Arrays.fill(row, n*n);for (int i=0; i<n; i++)dp[1<<i][i] = 0;for (int group=1; group<(1<<n); group++)for (int u=0; u<n; u++)for (int v=0; v<n; v++) {int src = 1 << u, dst = 1 << v;//group包含src,但是不包含dstif ((group & src)!=0 && (group & dst)==0 )dp[group|dst][v] = Math.min(dp[group][u] + dis[u][v], dp[group|dst][v]);}int minDis = 0x3f3f3f3f;for (int i=0; i<n; i++)minDis = Math.min(dp[(1<<n)-1][i], minDis);return minDis;}public static void main(String[] args){int[][] graph = new int[4][];graph[0] = new int[]{1,2,3};graph[1] = new int[]{0};graph[2] = new int[]{0};graph[3] = new int[]{0};int r = new ShortestPathVisitingAllNodesDP().shortestPathLength(graph);System.out.println(r);}
}
代码
关于FLoyd算法的介绍参考文章。
用二维数组记录任意两点之间的距离。dis[i][j]表示从i节点到j节点的距离。如果这两点之间有边,则dis的初始值是边的权重,否则是无穷大。
如果要让两点之间(例如a,b)的路程变短,那只能引入第三点(k)。如果a->k->b的距离小于a->b的距离,那就引入k。有时候可能需要引入不止一个节点,才能找到ab之间的最短路径:a->k1->k2…->b。每个顶点可能使得另外两个节点路程变短。
第二步,如果允许在所有节点之间跨越节点1。如果dis[i][1]+dis[1][j]<dis[i][j]dis[i][1]+dis[1][j]<dis[i][j]dis[i][1]+dis[1][j]<dis[i][j],那么dis[i][j]=dis[i][1]+dis[1][j]dis[i][j]=dis[i][1]+dis[1][j]dis[i][j]=dis[i][1]+dis[1][j]。需要用两个for循环实现替换。
第三步,如果允许在所有节点之间跨越节点1、2。如何做呢?我们需要在只允许经过1号顶点时任意两点的最短路程的结果下,再判断如果经过2号顶点是否可以使得i号顶点到j号顶点之间的路程变得更短。即判断e[i][2]+e[2][j]是否比e[i][j]要小。
第四步,进一步计算允许跨越节点1,2,3…,一直到节点n。最后的代码就是:
public void floyd(int n) {for(int k=0; k<n; k++)for(int i=0; i<n; i++)for(int j=0; j<n; j++)dis[i][j] = Math.min(dis[i][j], dis[i][k]+dis[k][j]);}
847. Shortest Path Visiting All Nodes(三)相关推荐
- ★☆★ lc 847. Shortest Path Visiting All Nodes
https://leetcode.com/problems/shortest-path-visiting-all-nodes/description/ 一笔画问题,一笔画完一个图中的所有点,求最短路径 ...
- 847. Shortest Path Visiting All Nodes(二)
输入:有N个节点的无向图,每个节点被标注为0,1,-N-1.graph[i][j]表示从节点i到节点j有一条边. 输出:每个节点都访问一次,至少需要几步. 规则:可以重复访问一个节点. 分析:这道题目 ...
- 847. Shortest Path Visiting All Nodes(一)
输入:一个无向图,各个节点的标签是0.1.2-N-1.graph[i][j]表示从节点i到节点j有一条边. 输出:返回每个节点都访问一遍需要的最少步骤. 规则:各个节点可以重复访问. 分析: 如果可以 ...
- Shortest Path(翻译)
http://noi.openjudge.cn/english/07/ There is a graph with N nodes. Given the length of each edge bet ...
- 程序员的算法课(19)-常用的图算法:最短路径(Shortest Path)
一.最短路径问题 [google笔试题]一个环形公路,给出相邻两点的距离(一个数组),求任意两点的最短距离,要求空间复杂度不超过O(N). 如果从有向图中某一顶点(称为源点)到达另一顶点(称为终点)的 ...
- P - The Shortest Path in Nya Graph HDU - 4725
P - The Shortest Path in Nya Graph HDU - 4725 最短路 不是 每两个点之间按层数设置边权 + 额外边权 TLE 是 相邻两层之间设置边权 + 额外边权 需注 ...
- [CF843D]Dynamic Shortest Path
[CF843D]Dynamic Shortest Path 题目大意: 给定一个带权有向图,包含\(n(n\le10^5)\)个点和\(m(m\le10^5)\)条边.共\(q(q\le2000)\) ...
- zoj 2760 How Many Shortest Path 最大流
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1760 Given a weighted directed graph ...
- OSPF(Open Shortest Path First开放式最短路径优先)
**协议** OSPF(Open Shortest Path First开放式最短路径优先)是一个内部网关协议(Interior Gateway Protocol,简称IGP),用于在单一自治系统(a ...
最新文章
- c语言中ai是什么,AICODE在C语言教学中应用研究.doc
- 高级Android开发面试汇总
- SELinux 入门
- Qt QSetting *.ini.lock
- 利用jquery操作ajax,利用jquery对ajax操作,详解原理(附代码)
- lol1月8日服务器维护,LOL1月16日更新维护到几点 8.1版本更新内容
- ubuntu中文输入法fcitx的安装以及出现方块的解决方法
- java 7 的新特性
- JQuery Dialog UI按钮文字国际化
- 个人开发—进度记录(一)
- 【元胞自动机】基于matlab元胞自动机短消息网络病毒传播仿真【含Matlab源码 1289期】
- Axure组件库资源
- Easyui 默认图标以及自定义图标
- 笔记:复旦IC卡专用芯片型号 -用于替代进口同类产品 - 草稿
- 苹果ipad怎么刷机_白苹果如何修复,为什么会出现白苹果
- 《Dreamweaver CS6 完全自学教程》笔记 第十五章:使用行为创建网页特效
- MATLAB绘图—三维网格绘图(mesh)
- Doxygen + Graphviz 安装(windows 10系统)
- kafka数据同步Elasticsearch深入详解
- ebay详情页html,eBay详情页商品的basic Description没有了?