【九度OJ】1008【加权无向图最短路径】
2014-08-08 12:06
531 查看
在网上查了一下,加权无向图最短路解法DFS和Dijkstra多一些,一般不用BFS
我选择用DFS,用时380MS,看了一下其他人的,最好的是240MS,用的是Dijkstra。都是采用邻接矩阵存储图结构。
在DFS的过程中,开始我的做法是,每找到一条从s到t的路径就存储起来,最后将最优路径输出。后来优化一下,在找路径的过程中,即DFS方法内部就可以判断出来(通过设置全局变量),这样最后DFS方法返回后,直接输出最短路径就可以。
DFS和Dijkstra的时间区别就在于核心方法DFS和Dijkstra上,所以还是Dijkstra优一些。这些算法要以后慢慢练习啦,比如之前的快排,今天遇到的Dijkstra,练习一次就好了。
代码:
通过这道题,我也得到了一些经验:
1.当每次while结束时,要将全局变量重新赋值
2.需要一个非常大的数的时候,使用Integer.MAX_VALUE
3.DFS找最短路径,要设置一个flag变量。递归找路径一般都需要设这样一个标记结点是否被访问的数组,如DFS,迷宫。而当访问过后,因为还需要找其他路径,所以不要忘记将flag变回false
我觉得这样练习OJ真的可以提高自己的编程能力,获得编程经验,继续加油!
我选择用DFS,用时380MS,看了一下其他人的,最好的是240MS,用的是Dijkstra。都是采用邻接矩阵存储图结构。
在DFS的过程中,开始我的做法是,每找到一条从s到t的路径就存储起来,最后将最优路径输出。后来优化一下,在找路径的过程中,即DFS方法内部就可以判断出来(通过设置全局变量),这样最后DFS方法返回后,直接输出最短路径就可以。
DFS和Dijkstra的时间区别就在于核心方法DFS和Dijkstra上,所以还是Dijkstra优一些。这些算法要以后慢慢练习啦,比如之前的快排,今天遇到的Dijkstra,练习一次就好了。
代码:
package Test1; import java.util.Scanner; public class Test53 { /** * by qr jobdu 1008 2014-8-7(8) graph:shortest path */ static int mind=Integer.MAX_VALUE; static int minp=Integer.MAX_VALUE; public static void main(String[] args) { Scanner scan = new Scanner(System.in); int n, m; n = scan.nextInt(); // number of node m = scan.nextInt(); // number of edge while (!(n == 0 && m == 0)) { int edgeD[][] = new int[n + 1][n + 1]; // node number is 1-->n int edgeP[][] = new int[n + 1][n + 1]; boolean flag[] = new boolean[n + 1]; // flag node pass situation(不要忘记加一个标记数组记录节点是否被访问过,迷宫也一样) for (int i = 1; i < n + 1; i++) { flag[i] = false; for (int j = 1; j < n + 1; j++) edgeD[i][j] = 0; // 0 represent no edge } for (int i = 0; i < m; i++) { int a = scan.nextInt(); int b = scan.nextInt(); edgeD[a][b] = scan.nextInt(); edgeD[b][a] = edgeD[a][b]; edgeP[a][b] = scan.nextInt(); edgeP[b][a] = edgeP[a][b]; } int s = scan.nextInt(); int t = scan.nextInt(); // dfs get the shortest path flag[s] = true; DFS(s, t, edgeD, edgeP, n, 0, 0, flag); //output result System.out.println(mind+" "+minp); mind=Integer.MAX_VALUE; //!important minp=Integer.MAX_VALUE; n = scan.nextInt(); m = scan.nextInt(); } } private static void DFS(int a, int b, int[][] edgeD, int[][] edgeP, int n, int d, int p, boolean flag[]) { if (a == b) { //在过程中就可以判断出来最小的,而无需返回再判断 if(mind>d || (mind==d && minp>p)){ mind=d; minp=p; } } else { for (int i = 1; i < n + 1; i++) { if (edgeD[a][i] != 0 && !flag[i]) { //flag[i]=false flag[i] = true; DFS(i, b, edgeD, edgeP, n, d + edgeD[a][i], p + edgeP[a][i], flag); flag[i]=false; //访问之后记得将状态变回来,无需创建一个一样大小的数组 } } } } }
通过这道题,我也得到了一些经验:
1.当每次while结束时,要将全局变量重新赋值
2.需要一个非常大的数的时候,使用Integer.MAX_VALUE
3.DFS找最短路径,要设置一个flag变量。递归找路径一般都需要设这样一个标记结点是否被访问的数组,如DFS,迷宫。而当访问过后,因为还需要找其他路径,所以不要忘记将flag变回false
我觉得这样练习OJ真的可以提高自己的编程能力,获得编程经验,继续加油!
相关文章推荐
- 九度 OJ 1008 最短路径问题
- 九度OJ-题目1008 最短路径问题
- 九度 OJ 题目1008:最短路径问题 (Dijstra 算法)
- 九度OJ 1447 最短路 1008 最短路径问题
- [九度OJ]1008.最短路径问题
- 九度OJ 1008:最短路径问题 (最短路)
- 最短路径问题—九度OJ1008 (2010年浙江大学研究生机试真题)
- 九度oj 题目1008:最短路径问题 【ZJU2010考研机试题4】【dij+dfs】
- 九度OJ 1008:最短路径问题 (最短路)
- 九度 oj 题目1008:最短路径问题
- 九度OJ-1008:最短路径问题
- 九度oj-1008-最短路径问题
- 九度OJ108 HDOJ3790:最短路径问题 迪杰斯特拉算法
- 九度 OJ 题目1447:最短路径(Floyd 算法)
- 九度OJ 1162:I Wanna Go Home(我想回家) (最短路径)
- 九度[1008]-最短路径问题
- 九度 oj 题目1100:最短路径
- 九度OJ 1162:I Wanna Go Home(我想回家) (最短路径)
- 九度1008,最短路径问题
- 九度:题目1008:最短路径问题