最短路径问题
来源:互联网 发布:js怎么判断是不是数组 编辑:程序博客网 时间:2024/05/17 23:13
可以这样分:
(1)单源最短路径:从某固定源点出发,求其到所有其他顶点的最短路径
(2)多源最短路径:求任意两顶点间的最短路径
也可以这样分:
(1)无权图的最短路算法:直接BFS解决
(2)有权图的最短路算法:Dijkstra算法,Dijkstra算法是按照递增的顺序找出到各个顶点的最短路。
---------- 其实可以把权重展开分解为一个个权重为1的路径,这不就是无权图的最短路径嘛,
---------- 然后用BFS不就是按照步数一步步递增地找出节点并加入到结果集 嘛
---------- Dijkstra算法的优化:将dist存在最小堆中,节省每次找最小值的时间
到现在,单源的有权可以用Dijkstra算法,无权可以用BFS,那多源呢?
方法1:直接将单源最短路算法调用|V|遍(V为number of Vetext)
方法2:Floyd 算法
解释:类似与DP,将节点编号为0..n-1,dp[k][i][j]为从i节点到j节点,只结果0..k这些节点所能到的最短距离,那如果节点k+1的加入能使dp[i][j]变小,那就说明找到了一条更短的,如此n次以后,最后就把全部的顶点之间的最短路径都求出来了
Floyd题目可参考:https://pta.patest.cn/pta/test/3512/exam/4/question/83400
哈利·波特要考试了,他需要你的帮助。这门课学的是用魔咒将一种动物变成另一种动物的本事。例如将猫变成老鼠的魔咒是haha,将老鼠变成鱼的魔咒是hehe等等。反方向变化的魔咒就是简单地将原来的魔咒倒过来念,例如ahah可以将老鼠变成猫。另外,如果想把猫变成鱼,可以通过念一个直接魔咒lalala,也可以将猫变老鼠、老鼠变鱼的魔咒连起来念:hahahehe。
现在哈利·波特的手里有一本教材,里面列出了所有的变形魔咒和能变的动物。老师允许他自己带一只动物去考场,要考察他把这只动物变成任意一只指定动物的本事。于是他来问你:带什么动物去可以让最难变的那种动物(即该动物变为哈利·波特自己带去的动物所需要的魔咒最长)需要的魔咒最短?例如:如果只有猫、鼠、鱼,则显然哈利·波特应该带鼠去,因为鼠变成另外两种动物都只需要念4个字符;而如果带猫去,则至少需要念6个字符才能把猫变成鱼;同理,带鱼去也不是最好的选择。
输入格式:
输入说明:输入第1行给出两个正整数N (≤100)和M,其中N是考试涉及的动物总数,M是用于直接变形的魔咒条数。为简单起见,我们将动物按1~N编号。随后M行,每行给出了3个正整数,分别是两种动物的编号、以及它们之间变形需要的魔咒的长度(≤100),数字之间用空格分隔。
输出格式:
输出哈利·波特应该带去考场的动物的编号、以及最长的变形魔咒的长度,中间以空格分隔。如果只带1只动物是不可能完成所有变形要求的,则输出0。如果有若干只动物都可以备选,则输出编号最小的那只。
输入样例:
6 113 4 701 2 15 4 502 6 505 6 601 3 704 6 603 6 805 1 1002 4 605 2 80
输出样例:
4 70
package HarrPotter;import java.util.*;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(), m = sc.nextInt(); int[][] dist = new int[1+n][1+n]; for(int i=0; i<=n ;i++) Arrays.fill(dist[i], 999999); for(int i=0; i<=n; i++) dist[i][i] = 0; for(int p=0; p<m; p++) { int i = sc.nextInt(), j = sc.nextInt(), d = sc.nextInt(); dist[i][j] = d; dist[j][i] = d; } // Floyd for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(dist[i][k] + dist[k][j] < dist[i][j]) dist[i][j] = dist[i][k] + dist[k][j]; // find min(max) int min = Integer.MAX_VALUE, idx = -1; for(int i=1; i<=n; i++) { int max = Integer.MIN_VALUE; boolean f = false; for(int j=1; j<=n; j++) { if(dist[i][j] > max) max = dist[i][j]; if(dist[i][j] == 999999) { f = true; break; } } if(f)continue; if(max < min) { min = max; idx = i; } } if(min == Integer.MAX_VALUE) System.out.println(0); else System.out.println(idx + " " + min); }}
Dijkstra 题目可参考:https://pta.patest.cn/pta/test/3512/exam/4/question/83400
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 30 1 1 201 3 2 300 3 4 100 2 2 202 3 1 20
输出样例:
3 40
package TravelPlan;import java.util.*;/* * 注意两者不可达是距离是选择MaxValue还是999999,还是-1 * adj, dist都要初始化好 * 注意path和cost添加的位置 */public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(), m = sc.nextInt(), s = sc.nextInt(), t =sc.nextInt(); int[][] adj = new int[n][n], fea = new int[n][n]; for(int[] i : adj)Arrays.fill(i, Integer.MAX_VALUE); while(m-- > 0) { int i = sc.nextInt(), j = sc.nextInt(), d = sc.nextInt(), f = sc.nextInt(); adj[i][j] = d;adj[j][i] = d; fea[i][j] = f;fea[j][i] = f; } // Dijkstra // initialization boolean[] collected = new boolean[n]; int[] dist = new int[n], cost = new int[n]; Arrays.fill(dist, Integer.MAX_VALUE); dist[s] = 0; while(true) { // find min int minIdx = -1, minDis = Integer.MAX_VALUE; for(int i=0; i<n; i++) { if(!collected[i] && dist[i] < minDis) { minDis = dist[i]; minIdx = i; } } // check min exists if(minIdx == -1)break; // update collected[minIdx] = true; for(int to=0; to<n; to++) if(adj[minIdx][to] != Integer.MAX_VALUE) { if(dist[to] > dist[minIdx] + adj[minIdx][to]) { dist[to] = Math.min(dist[to], dist[minIdx] + adj[minIdx][to]); cost[to] = cost[minIdx] + fea[minIdx][to]; } else if(dist[to] == dist[minIdx] + adj[minIdx][to] && cost[to] > cost[minIdx] + fea[minIdx][to]) { cost[to] = cost[minIdx] + fea[minIdx][to]; } } } System.out.println(dist[t] + " " + cost[t]); }}
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- sqoop import 报错:mysqld 没有开启
- 关于H5唤起APP遇到的问题
- 安卓手机判断手机联网状态
- 杭电 1088 字符处理
- hud 5012 Dice(隐式图的搜索 )
- 最短路径问题
- C++实现冒泡排序,选择排序,插入排序,快速排序,归并排序
- dubbo架构简要分析
- 面试
- 关于mysql-connector-net和C#.net
- 吐槽CSDN手机验证
- Redux-form系列教程
- 【Spring】基于c3p0连接池,实现数据库加解密连接MySQL数据库
- WebView截屏