多源最短路径Floyd、Floyd求最小环【模板】

Floyd算法:用来找出每对点之间的最短距离。图可以是无向图,也可以是有向图,边权可为正,也可以为负,唯一要求是不能有负环。 1.初始化:将Map[][]中的数据复制到Dist[][]中作为每对顶点之间的最短路径的初值,Pre[i][j] = i 表示 i 到 j 路径中 j 的前一节点。 2. k 从 1 到 N 循环 N 次,每次循环中,枚举图中不同的两点 i,j,如果Dist[i][j] > Dist[i][k] + Dist[k][j],则更新Dist[i][j] = Dist[i][k] + Dist[k][j],更新Pre[i][j] = Pre[k][j]。 只要图中不存在负环就可以得出正确的答案,关于Floyd算法对负环的判定,,参考下边Floyd求最小环。

const int MAXN = 110;const int INF = 0xffffff0;int Map[MAXN][MAXN], Dist[MAXN][MAXN],Pre[MAXN][MAXN];//Pre[i][j] = i表示i到j路径中j的前一节点void Floyd(int N){ //初始化}

如果求点u到点v能达到的最长边尽可能短的路径上最长边为多少,将循环内部改为如下代码:

int tMax; //这里边求的是能达到的路径上最长边最小为多少 if(Dist[i][k] > Dist[k][j])tMax = Dist[i][k];elsetMax = Dist[k][j];if(Dist[i][j] > tMax)Dist[i][j] = tMax;

Floyd求最小环 不能在Map[][]数组上直接计算,因为判断过程中用到了Map[][]原始值。

const int MAXN = 110;const int INF = 0xffffff0;int temp,Map[MAXN][MAXN],Dist[MAXN][MAXN],pre[MAXN][MAXN],ans[MAXN*3];void Solve(int i,int j,int k){temp = 0; //回溯,存储最小环while(i != j){ans[temp++] = j;j = pre[i][j];}ans[temp++] = i;ans[temp++] = k;}void Floyd(int N){for(int i = 1; i <= N; ++i)for(int j = 1; j <= N; ++j){Dist[i][j] = Map[i][j];pre[i][j] = i;}int MinCircle = INF; //最小环for(int k = 1; k <= N; ++k){for(int i = 1; i <= N; ++i){for(int j = 1; j <= N; ++j){if(i != j && Dist[i][j] != INF && Map[i][k] != INF && Map[k][j] != INF&& Dist[i][j] + Map[i][k] + Map[k][j] < MinCircle){MinCircle = min(MinCircle, Dist[i][j] + Map[i][k] + Map[k][j]);Solve(i,j,k); //回溯存储最小环}}}for(int i = 1; i <= N; ++i){for(int j = 1; j <= N; ++j){if(Dist[i][k] != INF && Dist[k][j] != INF &&Dist[i][k] + Dist[k][j] < Dist[i][j]){Dist[i][j] = Dist[i][k] + Dist[k][j];pre[i][j] = pre[k][j]; //记录点i到点j的路径上,j前边的点}}}}if(MinCircle == INF) //不存在环{printf(“No solution.\n”);return;}(i != temp-1)printf(“%d “,ans[i]);elseprintf(“%d\n”,ans[i]);}

记忆的屏障,曾经心动的声音已渐渐远去。

多源最短路径Floyd、Floyd求最小环【模板】

相关文章:

你感兴趣的文章:

标签云: