Floyd算法

多源最短路问题

给定一张 \(n\) 个点的有向图,要求出任意两点间的最短路。

算法简介

这是一个基于动态规划思想的最短路算法,它可以求解多源最短路问题。

时间复杂度为 \(O(n^3)\)

算法流程

\(dis[k][i][j]\) 表示从 \(i\)\(j\) ,只经过 \(1,2,...,k\) 的最短路长度。

故有 \(dis[i][j]=\min(dis[i][j],dis[i][k]+dis[k][j]),1≤i,j,k≤n\)

注意:在进行循环时要先枚举 \(k\)

于是我们有如下的代码:

for(Re int k=1;k<=n;k++)
{
	for(Re int i=1;i<=n;i++)
	{
		for(Re int j=1;j<=n;j++)
		{
			dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
		}
	}
}

典型例题

例题1

\(\text{problem}\) :给一个正权无向图,找一个权值和最小的环。

\(\text{solution}\)

首先我们知道这一定是个简单环。

于是考虑这个环是怎么构成的。

设环上编号最大的结点 \(u\)

\(f[u-1][x][y]\)\((u,x)\) , \((u,y)\) 共同构成了环。

故在 \(\text{Floyd}\) 的过程中枚举 \(u\) ,计算这个和的最小值即可。

例题2

\(\text{problem}\) :给定一个有向图,已知其中任意两点之间是否有连边,要求判断任意两点的连通性。

\(\text{solution}\)

这就是所谓图的传递闭包问题。

我们只需要按照 \(\text{Floyd}\) 的过程,逐个加入点判断一下。

只是此时的取 \(\min\) 变成了位运算( 或运算和与运算 )。

for(Re int k=1;k<=n;k++)
{
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			f[i][j]|=f[i][k]&f[k][j];
		}
	}
}
posted @ 2020-11-21 15:16  kebingyi  阅读(129)  评论(0编辑  收藏  举报