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];
}
}
}