弗洛伊德算法

使用的类型题:有向图求两点之间最短距离。

 以此demo为例:

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class FloydDemo {
    //常量 设置为两节点之间最长距离
    private final static int MAX_DISTANCE = 1001;
    /**
     * 弗洛伊德算法
     * @param n 图中节点数量
     * @param roads 输入 有向图信息
     *              存储格式如图所示
     *              {
     *              {v0,u0,l0}
     *              {v1,u1,l1},
     *              {v2,u2,l2}
     *              }
     *              vi为出发点,ui为目的地,li为路径长度
     * @param resType resType 返回值类型
     *                true --> 返回 distance
     *                false --> 返回 path
     * @return
     */
    public int[][] floyd(int n , int[][] roads , boolean resType){
        int[][] distance = new int[n][n]; //最短距离数组
        int[][] path = new int[n][n];    //最短路径存储
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                distance[i][j] = i == j ? 0 : MAX_DISTANCE;
                path[i][j] = -1;
            }
        }//<-- 初始化 d p 状态;此时 d p 状态为 -2;
        for (int i = 0; i < roads.length; i++) {
            distance[roads[i][0]][roads[i][1]] = roads[i][2];
            path[roads[i][0]][roads[i][1]] = roads[i][0];
        }//<-- 第二次初始化 d p 状态;此时 d p 状态为 -1;
        int target = 0; //target 标识当前 d p 状态 为 0;
        while (target < n) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (i == target || j == target || i == j) {
                        continue;
                    } else {
                        if (distance[i][j] > distance[i][target] + distance[target][j]) {
                            distance[i][j] = distance[i][target] + distance[target][j];
                            path[i][j] = path[target][j];
                        }
                    }
                }
            }
            printIntArrayArray(distance);
            target += 1;
        }
        return resType?distance:path;
    }

    /**
     * Floyd Path存储路径解析
     * @param start 起点位置
     * @param end 终点位置
     * @param path path存储
     * @return 路径
     */
    public List<Integer> pathResolving (int start,int end,int[][] path){
        List<Integer> sePath = new LinkedList<Integer>();
        Stack<Integer> stack = new Stack<Integer>();
        int now = end;
        while (now != start){
            stack.push(now);
            now = path[start][now];
        }
        sePath.add(start);
        while (!stack.isEmpty()){
            sePath.add(stack.pop());
        }
        return sePath;
    }
    public void printIntArrayArray(int[][] arrays){
        for (int[] array : arrays) {
            System.out.print("{ ");
            for (int i : array) {
                System.out.print(i);
                System.out.print(",");
            }
            System.out.println(" }");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        FloydDemo floydDemo = new FloydDemo();
        int[][] roads = {{0,1,2},{0,2,4},{1,0,2},{1,2,1},{2,1,1},{2,0,4}};
        int[][] distance = floydDemo.floyd(3, roads, true);
        //int[][] path = floydDemo.floyd(3, roads, false);
        System.out.println();
        //floydDemo.printIntArrayArray(distance);
        //floydDemo.printIntArrayArray(path);
//        for (Integer integer : floydDemo.pathResolving(1, 0, path)) {
//            System.out.println(integer);
//        }
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值