Floyd算法:用动态规划求解多源(全源)最短路径
来源:互联网 发布:ubuntu原版和麒麟 编辑:程序博客网 时间:2024/06/01 08:54
loyd算法可以说是Warshall算法的扩展,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3)。
Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB) = Dis(AX) + Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。
但是这里我们要注意循环的嵌套顺序,如果把检查所有节点X放在最内层,那么结果将是不正确的,为什么呢?因为这样便过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了。
for(int k=0; k<vexnum; ++k) for(int i=0; i<vexnum; ++i) for(int j=0; j<vexnum; ++j) if( dist[i][j] > dist[i][k]+dist[k][j] ) { dist[i][j] = dist[i][k] + dist[k][j]; path[i][j] = path[k][j]; } }
做了一道谷歌算法题,题目很简单。
Problem
Company G has a main campus with N offices (numbered from 0 to N - 1) and Mbidirectional roads (numbered from 0 to M - 1). The ith road connects a pair of offices (Ui, Vi), and it takes Ci minutes to travel on it (in either direction).
A path between two offices X and Y is a series of one or more roads that starts at X and ends at Y. The time taken to travel a path is the sum of the times needed to travel each of the roads that make up the path. (It's guaranteed that there is at least one path connecting any two offices.)
Company G specializes in efficient transport solutions, but the CEO has just realized that, embarrassingly enough, its own road network may be suboptimal! She wants to know which roads in the campus are inefficient. A road is inefficient if and only if it is not included in any shortest paths between any offices.
Given the graph of offices and roads, can you help the CEO find all of the inefficient roads?
Input
The first line of the input gives the number of test cases, T. T test cases follow. Each case begins with one line with two integers N and M, indicating the number of offices and roads. This is followed by M lines containing three integers each: Ui, Vi and Ci, indicating the ith road is between office Ui and office Vi, and it takes Ci minutes to travel on it.
Output
For each test case, output one line containing "Case #x:", where x is the test case number (starting from 1). Then output the road numbers of all of the inefficient roads, in increasing order, each on its own line. (Note that road 0 refers to the first road listed in a test case, road 1 refers to the second road, etc.)
Limits
0 < Ci ≤ 1000000.
Small dataset
1 ≤ T ≤ 10.
1 ≤ N = M ≤ 100.
Large dataset
1 ≤ T ≤ 3.
1 ≤ N ≤ 100.
1 ≤ M ≤ 10000.
Sample
可用Floyd算法求解:package google;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.util.Arrays;import java.util.List;import java.util.ArrayList;public class gCampus1 {public static void main(String [] args){try { FileReader inf = new FileReader("C-large-practice.in"); BufferedReader in = new BufferedReader(inf); BufferedWriter out=new BufferedWriter(new FileWriter("out.txt")); int n = Integer.parseInt(in.readLine()); for(int i = 1;i <= n;i++){ String [] kk = in.readLine().split(" "); int vn = Integer.parseInt(kk[0]); int [][] a = new int[vn][vn]; int [][] a_r = new int[vn][vn]; int mn = Integer.parseInt(kk[1]); boolean[] roads = new boolean[mn]; int [] t1 = new int[mn]; int [] t2 = new int[mn]; int [] t3 = new int[mn]; Arrays.fill(roads,false); for(int k = 0;k < vn;k++){ for(int j = 0;j < vn;j++){ if(a[k][j] == 0 && k != j){ a[k][j] = 900000000; } } } for(int j = 0;j < mn;j++){ String []temp = in.readLine().split(" "); int v1 = Integer.parseInt(temp[0]); int v2 = Integer.parseInt(temp[1]); int len = Integer.parseInt(temp[2]); t1[j] = v1; t2[j] = v2; t3[j] = len; if(a[v1][v2] < len){ roads[j] = true; System.out.println(len+" "); continue; } //if(a[v1][v2] == 0 || a[v1][v2] > len){ a[v1][v2] = len; a[v2][v1] = len; a_r[v1][v2] = j; a_r[v2][v1] = j; //} } /*boolean [] visit = new boolean [vn]; Arrays.fill(visit, false); visit[0] = true; List<Integer> re = new ArrayList<Integer>(); DijkstraPath(a,0,a_r,re,visit); for(int j = 0;j < re.size();j++){ roads[(int)re.get(j)] = true; for(int k = 0;k < vn;k++){ } }*/ for(int k = 0;k < vn;k++){ for(int j = 0;j < vn;j++){ for(int h = 0;h < vn;h++){ a[j][h] = Math.min(a[j][h], a[j][k]+a[k][h]); } } } for(int j = 0;j < mn;j++){ if(t3[j] > a[t1[j]][t2[j]]){ roads[j] = true; } } out.write("Case #" + i + ":"); for(int j = 0;j < mn;j++){ if(roads[j]){ out.newLine();; out.write(String.valueOf(j)); } } out.newLine(); } in.close(); out.close(); }catch(Exception e){System.out.println("error");}}public static void DijkstraPath(int [][] a, int v0, int [][] a_r,List<Integer> re,boolean []visit){int n = a.length;if(v0 >= n-1){return;}int [] dist = new int [n];int [] last = new int [n];Arrays.fill(dist, -1);Arrays.fill(last, -1);Arrays.fill(visit, v0+1, n, false);int count = 1;dist[v0] = 0;visit[v0] = true;for(int i = 0 ;i < n;i++){if(a[v0][i] > 0){dist[i] = a[v0][i];last[i] = v0;}}while(count < n){int target = -1;int min = Integer.MAX_VALUE;for(int i = 0;i < n;i++){if(!visit[i] && i!=v0 && dist[i] != -1 && dist[i] < min){min = dist[i];target = i;}}if(target == -1){break;}re.add(a_r[last[target]][target]);if(target != -1){visit[target] = true;count++;for(int i = 0;i < n;i++){if(i != target && !visit[i] && a[target][i] > 0){if(dist[i] < 0){dist[i] = a[target][i];last[i] = target;}else if(dist[i] > dist[target] + a[target][i]){dist[i] = dist[target] + a[target][i];last[i] = target;}}}}}DijkstraPath(a,v0+1,a_r,re,visit);}}
- Floyd算法:用动态规划求解多源(全源)最短路径
- 动态规划、最短路径、Floyd算法
- 迪杰斯特拉算法求解最短路径(三)---《动态规划》
- 多源有权图的最短路径 floyd算法(动态规划能解决负权边)7.1.3
- [Qt][Floyd算法] 动态规划求解最短行驶路径 源码及演示程序
- 动态规划——Floyd最短路径算法
- floyd算法求解最短路径
- Floyd Warshell 算法求解多源点最短路径
- 动态规划实例(十五):最短路径Floyd
- 动态规划---->每对定点之间的最短路径 Floyd(弗洛伊德)算法
- 动态规划之所有点对的最短路径问题(Floyd算法)
- 数据结构和算法——用动态规划求解最短路径问题
- 弗洛伊德(Floyd)算法求解图的最短路径
- Floyd算法求解所有顶点间的最短路径
- python实现 Floyd算法求解最短路径距离问题
- 最短路径算法(floyd算法)
- 【动态规划】每对顶点之间的最短路径之Floyd-Warshall算法
- 动态规划算法--最短路径问题
- 水桶定律
- 工作周报051
- 计算机视觉领域稍微容易中的期刊(二)
- iOS开发--UICollectionView网格视图
- mysql怎么查询条件以另一个表中条件进行查询
- Floyd算法:用动态规划求解多源(全源)最短路径
- 4.2 内核工作队列原理汇总
- Android下的挂钩(hook)和代码注入(inject)
- 蘑菇管理
- 源码安装erlang
- java中的强引用、软引用、弱引用、虚引用
- Ubuntu Linux下设置IP的配置命令
- FIR滤波器的FPGA实现
- 30分钟搞定STL