floyd.java 3.5 KB
Newer Older
qq_36480062's avatar
c  
qq_36480062 已提交
1 2
package graph;

qq_36480062's avatar
c  
qq_36480062 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
import java.util.Scanner;

/**
 * 给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。
 * 再给定k个询问,每个询问包含两个整数x和y,表示查询从点x到点y的最短距离,如果路径不存在,则输出“impossible”。
 * 数据保证图中不存在负权回路。
 * 输入格式
 * 第一行包含三个整数n,m,k
 * 接下来m行,每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z。
 * 接下来k行,每行包含两个整数x,y,表示询问点x到点y的最短距离。
 * 输出格式
 * 共k行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出“impossible”。
 * 数据范围
 * 1≤n≤200,
 * 1≤k≤n^2
 * 1≤m≤20000,
 * 图中涉及边长绝对值均不超过10000。
 * 输入样例:
 * 3 3 2
 * 1 2 1
 * 2 3 2
 * 1 3 1
 * 2 1
 * 1 3
 * 输出样例:
 * impossible
 * 1
 * 多源最短路问题,采用Floyd算法,时间复杂度为O(n^3)。
 * Floyd算法的思想是动态规划。设d[i][j]表示i点到j点的最短距离,
 * i点到j点中间经过某点k,则状态转移方程为d[i][j] = min(d[i][k] + d[k][j],d[i][j])(1<=k<=n);
 * 然后用三重循环实现该状态扩散的过程即可。注意对中间节点k的枚举需要放在循环的最外层,否则会出错。
 * 使用邻接矩阵存图
 * 边长最多10000最多20000边,则最长路径就是2*10^8
 * 初始化为int/2即可
 * 即使全是负权边,int/2-2*10^8,无穷-常数还是无穷
 * 如何判别无穷呢,显然 int/4>2*10^8
qq_36480062's avatar
c  
qq_36480062 已提交
39
 *
qq_36480062's avatar
c  
qq_36480062 已提交
40
 */
qq_36480062's avatar
c  
qq_36480062 已提交
41 42
public class floyd {
    public static void main(String[] args) {
qq_36480062's avatar
c  
qq_36480062 已提交
43
        Scanner sc = new Scanner(System.in);
qq_36480062's avatar
c  
qq_36480062 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
//        n = sc.nextInt();
//        m = sc.nextInt();
//        k = sc.nextInt();
//        int x, y, z, t = Integer.MAX_VALUE / 2;
//        for (int i = 1; i <= n; i++) {
//            for (int j = 1; j <= n; j++) {
//                if (i == j) g[i][j] = 0;
//                else g[i][j] = t;
//            }
//        }
//        for (int i = 0; i < m; i++) {
//            x = sc.nextInt();
//            y = sc.nextInt();
//            z = sc.nextInt();
//            g[x][y] = Math.min(g[x][y], z);
//        }
        int[][] g = {
                {8, 20, 32, 56, 54, 40},
                {20, 10, 48, 64, 34, 20},
                {32, 48, 8, 24, 54, 42},
                {56, 64, 24, 10, 30, 50},
                {54, 34, 54, 30, 6, 28},
                {40, 20, 42, 50, 28, 12}};
//        floyd(g);
        for (int k = 0; k < 6; k++) {
            for (int i = 0; i < 6; i++) {
                for (int j = 0; j < 6; j++) {
                    g[i][j] = Math.min(g[i][k] + g[k][j], g[i][j]);
                }
qq_36480062's avatar
c  
qq_36480062 已提交
73 74
            }
        }
qq_36480062's avatar
c  
qq_36480062 已提交
75 76 77 78 79
        for (int i = 0; i < 6; i++) {
            for (int j = 0; j < 6; j++) {
                System.out.print(g[i][j] + " ");
            }
            System.out.println();
qq_36480062's avatar
c  
qq_36480062 已提交
80
        }
qq_36480062's avatar
c  
qq_36480062 已提交
81 82 83 84 85 86
//        while (k-- != 0) {
//            x = sc.nextInt();
//            y = sc.nextInt();
//            if (g[x][y] > t / 2) System.out.println("Imposs");
//            else System.out.println(g[x][y]);
//        }
qq_36480062's avatar
c  
qq_36480062 已提交
87
    }
qq_36480062's avatar
c  
qq_36480062 已提交
88

qq_36480062's avatar
c  
qq_36480062 已提交
89
    static void floyd(int[][] g) {
qq_36480062's avatar
c  
qq_36480062 已提交
90 91 92 93 94 95 96
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    g[i][j] = Math.min(g[i][k] + g[k][j], g[i][j]);
                }
            }
        }
qq_36480062's avatar
c  
qq_36480062 已提交
97
    }
qq_36480062's avatar
c  
qq_36480062 已提交
98

qq_36480062's avatar
c  
qq_36480062 已提交
99
    static int n = 5, m, k;
qq_36480062's avatar
c  
qq_36480062 已提交
100

qq_36480062's avatar
c  
qq_36480062 已提交
101
    //   static int[][] g = new int[210][210];
qq_36480062's avatar
c  
qq_36480062 已提交
102
}