算法——图论——最短路径——Floyd / 传递闭包

目录

Floyd-Warshall(弗洛伊德)算法

传递闭包

[一、试题 算法训练 盾神与离散老师2](#一、试题 算法训练 盾神与离散老师2)


Floyd-Warshall(弗洛伊德)算法

  • 求所有顶点到所有顶点的最短路径问题
  • 弗洛伊德算法(Floyd-Warshall algorithm)是一种用于寻找图中所有顶点对之间最短路径的动态规划算法。
  • 该算法可以处理带有负权边但不含负权环的加权有向图或无向图。
  • 弗洛伊德算法的核心思想是利用三重循环遍历所有顶点,逐步更新每对顶点之间的最短路径的信息。

弗洛伊德算法的示例代码:

java 复制代码
import java.util.Arrays;

public class FloydWarshall {

    public static void main(String[] args) {
        int INF = 99999; // 表示无穷大
        int[][] graph = {
            {0, 5, INF, 10},
            {INF, 0, 3, INF},
            {INF, INF, 0, 1},
            {INF, INF, INF, 0}
        };

        floydWarshall(graph);
    }

    public static void floydWarshall(int[][] graph) {
        int V = graph.length;
        int[][] dist = new int[V][V];

        // 初始化距离矩阵为图的邻接矩阵
        for (int i = 0; i < V; i++) {
            for (int j = 0; j < V; j++) {
                dist[i][j] = graph[i][j];
            }
        }

        // 迭代更新距离矩阵
        for (int k = 0; k < V; k++) {
            for (int i = 0; i < V; i++) {
                for (int j = 0; j < V; j++) {
                    if (dist[i][k] + dist[k][j] < dist[i][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                    }
                }
            }
        }

        // 打印最短路径距离
        printSolution(dist);
    }

    public static void printSolution(int[][] dist) {
        int V = dist.length;
        System.out.println("距离矩阵:");
        for (int i = 0; i < V; ++i) {
            for (int j = 0; j < V; ++j) {
                if (dist[i][j] == 99999) {
                    System.out.print("INF ");
                } else {
                    System.out.print(dist[i][j] + " ");
                }
            }
            System.out.println();
        }
    }
}

传递闭包

  • 给定一个集合,以及若干对元素之间的传递关系,传递闭包问题是求所有元素之间的传递(连通)关系。
  • 例如,包括3个元素的集合{a,b,c},给定传递关系a-->b, b-->c,那么可推导出a-->c
  • 用Floyd算法解决传递闭包问题
  • 可用bitset优化复杂度

传递闭包的示例代码:

java 复制代码
    // 使用Floyd算法计算最短路径
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    // 如果经过节点k可以从节点i到达节点j,则更新传递闭包矩阵
                    if (matrix[i][k] == 1 && matrix[k][j] == 1) {
                        matrix[i][j] = 1;
                    }
                }
            }
        }

一、试题 算法训练 盾神与离散老师2

问题描述

  有一天,盾神觉得自己离散课快要挂了,于是亲自找到离散老师WH,请教如何才能不挂科。WH老师说,只要你做出下面那题,你就可以不挂了!但是盾神不会做T_T只能请教你了。

  有N个人,i和j可能认识,可能不认识。i一定认识i。如果i认识j,j不一定认识i。但是如果i认识j,j认识k,i必定认识k。给出目前掌握的N个人互相的认识关系,求用已知的关系推断出来的N个人互相的人事关系。
输入格式

  输入第一行为一个数N。

  接下来是一个N*N的矩阵,第i行第j个数是1的话表示i认识j,0的话表示i不一定认识j。不会出现除0和1之外的其他数。数与数之间用一个空格隔开。第i行第i列不一定是1。
输出格式

  输出一个N*N的矩阵,第i行第j列的意思如输入。数与数之间用一个空格隔开。第i行第i列必须是1。
样例输入

  3

  0 1 0

  0 0 1

  0 0 0
样例输出

  1 1 1

  0 1 1

  0 0 1
数据规模和约定

  N<=500
分析:

  • 使用Floyd算法解决,套用代码即可
  • 一个三重for循环
java 复制代码
package no1_1;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt();
        int[][] matrix = new int[n+1][n+1];
        for (int i = 1; i <= n; i++) {
            scanner.nextLine();
            for (int j = 1; j <= n; j++) {
                matrix[i][j] = scanner.nextInt();
                if(i == j) {//自己一定认识自己
                    matrix[i][j] = 1;
                }
            }
        }

        // 使用多重循环直接更新矩阵中的间接关系
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (matrix[i][j] == 0 && matrix[i][k] == 1 && matrix[k][j] == 1) {
                        matrix[i][j] = 1;
                    }
                }
            }
        }
        //打印矩阵
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}
相关推荐
青少儿编程课堂11 分钟前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i11 分钟前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
乐迪信息2 小时前
港口船舶逆行怎么管?AI防爆摄像机搭载智能检测算法
大数据·人工智能·深度学习·算法·计算机视觉
Sirens.3 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
和裕3 小时前
全纸结构重型纸箱能否满足 1 吨以上设备出口熏蒸豁免要求?通关合规性全解析
大数据·运维·网络·人工智能·算法
tangguofeng3 小时前
不带头结点的链队操作集(不含InitFlag)(C语言版)
算法
苏打豆5 小时前
CRISP源码阅读——基于ROS2力矩反馈控制器与速度加速度零空间
c++·线性代数·算法·矩阵·机器人
蛋蛋的就会顺顺的5 小时前
hot100——矩阵
java·数据结构·算法·leetcode·力扣
老歌老听老掉牙5 小时前
麻花钻切屑形态演变的力学机制与临界条件分析
python·算法·钻头
zhangfeng11336 小时前
国产GPU/AI算力芯片现状(修订完整版 · 截至2026年9月
人工智能·算法·ai编程·npu