Floyd算法详解

简介 :

  • Floyd算法是解决任意两点间的最短路径的一种算法
  • Floyd算法是一个经典的动态规划算法
  • Floyd算法的时间复杂度为O(N3),空间复杂度为O(N2)

算法描述与原理:

首先我们的目标是寻找从点i到点j的最短路径。从一个节点 i 到 节点 j,无非就是两种情况

  • 直接从 i 点 到 j 点
  • 如 i 点出发经过若干个点到达 j 点
要找出最 i 节点 到 j 节点的最短距离,我们可以用dis(i,j)来表示 i 到 j的距离,对于 i 节点 到 j 节点 的每一个点 k ,我们可以得出

 dis(i,k)+dis(k,j)<dis(i,j)

当这个式子成立时我们可以证明,i直接到j的距离不是最短距离,这时我们可以写出这样一个式子

 dis(i,j)=dis(i,k)+dis(k,j)

这样的话 我们就只需要遍历所有节点 一次都进行上面的操作,这样dis(i,j) 就是 i 节点到 j 节点的最短距离

具体操作

  • 对每两点的距离都赋予一个权值(在这里可以理解为距离)
  • 对于每对点 x 和 y,判断是否有 一个顶点 x 到 z 再到 y的距离比直接x 到 y的距离要短

具体代码 :

import java.util.*;
import java.io.*;

public class Main{
    private static final int MAX = 1<<29;
    private static int[][] map;
    private static Scanner scanner;
    private static int num = 0,mum  = 0;
    static {
        map = new int[100][100];
        scanner = new Scanner(new BufferedInputStream(System.in));
    }
    public static void main(String[] args) {
        while(scanner.hasNext()) {
            num = scanner.nextInt();
            mum = scanner.nextInt();
            /*初始化数组*/
            for (int i = 1; i<=num; i++) {
                for (int j = 1; j<=num; j++) {
                    if (i!=j) {
                        map[i][j] = MAX;                                    
                    }else {
                        map[i][j] = 0; //对于每个点自己到自己的权值(距离)为 0 
                    }                   
                }           
            }
            /*手动添加每两个点之间的距离*/
            for (int i = 1; i<=mum; i++) {
                int x,y,z;
                x = scanner.nextInt();
                y = scanner.nextInt();
                z = scanner.nextInt();
                map[x][y] = z;          
            }
            /* 核心算法,对于num个k 从 i 点 k点 再到 j点 与直接 i 到 j的距离相比较 取最小值*/
            for (int k = 1;k <= num ; k++) {
                    for (int i = 1;i <= num ; i++) {
                        for (int j = 1; j <= num; j++) {
                            if (i!=j&&j!=k) {
                                map[i][j] = Math.min(map[i][j],map[i][k]+map[k][j]);
                            }
                         }
                    }
                }   
                /* 打印 每两个点之间的最短路径*/
                for (int i = 1; i <= num; i++ ) {
                    for (int j = 1; j <= num; j++ ) {
                        System.out.printf("dis %d %d = %d\n",i,j,map[i][j]);
                    }
                }

        }
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值