图论 之 弗洛伊德算法求解全源最短路径

文章目录

  • 题目

  • Floyd算法适合用于求解多源的最短路径的问题,相比之下,Dijkstra算法适合用于求解单源的最短路径的问题,并且,当边的权值只有1的时候,我们还能使用BFS求解最短路径的问题

图论 之 BFS
图论 之 迪斯科特拉算法求解最短路径

灵神讲解

  • Floyd算法可以从递归中得到,相对应的,我们也有使用记忆化搜索动态规划进行求解

递归方式的模版

python 复制代码
@cache
def dfs(k,i,j):
	if k < 0:
		# w[i][j]为i到j的权值
		return w[i][j]
	return min(dfs(k-1,i,j),dfs(k-1,i,k)+dfs(k-1,k,j))

动态规划的模版

python 复制代码
        # 首先构造图,无向图
        e = [[float('inf')]*n for _ in range(n)]
        for f,t,d in edges:
            e[f][t] = d 
            e[t][f] = d 

        # 三维数组,dp[k][i][j]表示从节点i到节点j并且中间结点<=k-1的最短距离(故意开多一个位置)
        dp = [[[0]*n for _ in range(n)] for _ in range(n+1)]
        # 初始化,dpp[0][i][j] = e[i][j]
        dp[0] = e[:]

        for k in range(n):
            for i in range(n):
                for j in range(n):
                    # 通过枚举找到最佳的情况
                    dp[k+1][i][j] = min(dp[k][i][j],dp[k][i][k]+dp[k][k][j])
# 最终的dp[n][i][j]就是所需的答案                 

题目

1334.阈值距离内邻居最少的城市

1334.阈值距离内邻居最少的城市

思路分析:我们直接使用Floyd算法进行求解即可

  • 递归求解
python 复制代码
class Solution:
    def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
        # 弗洛伊德算法其实就是递归就可以解决
        # 首先构造图,无向图
        e = [[float('inf')]*n for _ in range(n)]
        for f,t,d in edges:
            e[f][t] = d 
            e[t][f] = d 
        
        # 定义求解的弗洛伊德算法
        @cache
        def dfs(k,i,j):
            if k < 0:
                return e[i][j]
            return min(dfs(k-1,i,j),dfs(k-1,i,k)+dfs(k-1,k,j))
        ans = 0
        cur = float('inf')
        # 开始调用
        for i in range(n):
            count = 0
            for j in range(n):
                if i != j and dfs(n-1,i,j) <= distanceThreshold:
                    count+=1
            # 更新
            if count <= cur:
                cur = count
                ans = i 
        return ans
  • 动态规划,动态规划的效率高一点
python 复制代码
class Solution:
    def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
        # 弗洛伊德算法其实就是递归就可以解决
        # 首先构造图,无向图
        e = [[float('inf')]*n for _ in range(n)]
        for f,t,d in edges:
            e[f][t] = d 
            e[t][f] = d 

        # 三维数组,dp[k][i][j]表示从节点i到节点j并且中间结点<=k-1的最短距离(故意开多一个位置)
        dp = [[[0]*n for _ in range(n)] for _ in range(n+1)]
        # 初始化,dpp[0][i][j] = e[i][j]
        dp[0] = e[:]

        for k in range(n):
            for i in range(n):
                for j in range(n):
                    # 通过枚举找到最佳的情况
                    dp[k+1][i][j] = min(dp[k][i][j],dp[k][i][k]+dp[k][k][j])
        
        ans = 0
        cur = float('inf')
        # 开始调用
        for i in range(n):
            count = 0
            for j in range(n):
                if i != j and dp[n][i][j] <= distanceThreshold:
                    count+=1
            # 更新
            if count <= cur:
                cur = count
                ans = i 
        return ans
相关推荐
lcj2511几秒前
深入理解指针(4):qsort 函数 & 通过冒泡排序实现
c语言·数据结构·算法
fie88892 分钟前
基于MATLAB的转子动力学建模与仿真实现(含碰摩、不平衡激励)
开发语言·算法·matlab
唐梓航-求职中8 分钟前
编程大师-技术-算法-leetcode-1472. 设计浏览器历史记录
算法·leetcode
_OP_CHEN12 分钟前
【算法基础篇】(五十八)线性代数之高斯消元法从原理到实战:手撕模板 + 洛谷真题全解
线性代数·算法·蓝桥杯·c/c++·线性方程组·acm/icpc·高斯消元法
唐梓航-求职中19 分钟前
编程大师-技术-算法-leetcode-355. 设计推特
算法·leetcode·面试
少许极端26 分钟前
算法奇妙屋(二十八)-递归、回溯与剪枝的综合问题 1
java·算法·深度优先·剪枝·回溯·递归
仰泳的熊猫28 分钟前
题目1453:蓝桥杯历届试题-翻硬币
数据结构·c++·算法·蓝桥杯
唐梓航-求职中28 分钟前
技术-算法-leetcode-1606. 找到处理最多请求的服务器(易懂版)
服务器·算法·leetcode
啊阿狸不会拉杆29 分钟前
《机器学习导论》第 10 章-线性判别式
人工智能·python·算法·机器学习·numpy·lda·线性判别式
会叫的恐龙30 分钟前
C++ 核心知识点汇总(第11日)(排序算法)
c++·算法·排序算法