多源最短路问题
给定一张 (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];
}
}
}