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

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

( ext{solution})

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

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

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

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

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

例题2

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

( ext{solution})

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

我们只需要按照 ( ext{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];
		}
	}
}
原文地址:https://www.cnblogs.com/kebingyi/p/14015768.html