多源最短路·floyd && 最小环算法

其实我已经会了。。但今天写错了一次。。。。实在恐怖。。所以我决定还是深度解析这个floyd算法

Floyd-warshall

1.摆出问题

先摆出最简单问题,给你图,询问a,b求a,b间最短路

不会floyd的时候,,我是扎扎实实的对每个点求单源最短路。。。

后来学了floyd。。。floyd就是求任意两点间的最短路的


2.给出floyd算法

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


非常简洁的代码

3.解释代码

先声明:floyd就一个动态规划

我们定义opt[i][j][k] 表示i->j的只过标号1->k的点的最短路

那么如果它没过点k的话,opt[i][j][k] = opt[i][j][k-1];

如果过点k opt[i][j][k] = opt[i][k][k-1] + opt[k][j][k-1];

然后综合一下就是opt[i][j][k] = min(opt[i][k][k-1] + opt[k][j][k-1],opt[i][j][k] = opt[i][j][k-1]);

最后的维度k可以压缩掉,就成了opt[i][j] = min(opt[i][j],opt[i][k]+opt[k][j]);


floyd就这么开心的讲完了~有向图无向图神马的自己改去~


最小环


环,,i,j,k三点,环长则为三点 两两间距,

且路不能有交点,

所以,我们想到map[i][j] + dist[i][k] + dist[j][k]

map记录最短路,dist记录直接相连的边

只要map[i][j]不过k点就算得出一个环

让最短路不过k点

想到floyd的dp方程

结果呼之欲出了吧~~我就不说了,直接上伪代码

/*由于是无向图所以计算可以少一半。。*/
dist = map;
k = 1->n;
{
i = 1->k-1;
j = 1->i-1;
ans = min(ans,map[i][j] +dist[i][k] + dist[j][k] );//需注意的是i,j,k三点不能相同,所以循环终止是k-1,i-1。。。
i = 1->n;
j = 1->i;
dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);
}

就这样了,不懂或存在异议的或有新想法的欢迎讨论啊~~

你可能感兴趣的:(算法)