多源最短路径Floyd、Floyd求最小环【模板】
2015-05-04 21:58
369 查看
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求最小环。
如果求点u到点v能达到的最长边尽可能短的路径上最长边为多少,将循环内部改为如下代码:
Floyd求最小环
不能在Map[][]数组上直接计算,因为判断过程中用到了Map[][]原始值。
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) { //初始化 for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { Dist[i][j] = Map[i][j]; Pre[i][j] = i; } } for(int k = 1; k <= N; ++k) { for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { //如果Dist[i][j] > Dist[i][k] + Dist[k][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]; //更新Pre[i][j] } } } } }
如果求点u到点v能达到的最长边尽可能短的路径上最长边为多少,将循环内部改为如下代码:
int tMax; //这里边求的是能达到的路径上最长边最小为多少 if(Dist[i][k] > Dist[k][j]) tMax = Dist[i][k]; else tMax = 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; } //如果求出最小环为负的,原图必定存在负环 for(int i = 0;i < temp; ++i) //输出最小环 if(i != temp-1) printf("%d ",ans[i]); else printf("%d\n",ans[i]); }
相关文章推荐
- 多源最短路径Floyd、Floyd求最小环【模板】
- 最短路径算法Dijkstra && SPFA && Floyd 代码实现模板
- DS实验题 Floyd最短路径 & Prim最小生成树
- 图论之最短路径 弗洛伊德算法(Floyd)多源最短
- Floyd 多源最短路径
- 多源最短路径---Floyd-Warshall算法
- 多源最短路径算法---Floyd-Warshall
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 多源最短路径 Floyd 算法(有向图) C实现 ~
- Spark GraphX之Dijkstra(单源最短路径)、Prime(最小生成树)、FloydWarshall(多源最短路径)
- 最短路径(Floyd 模板题)
- (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍
- 多源最短路径问题-floyd warshall
- 图(Graph)——最小生成树、最短路径、Kruskal、Dijkstra、Floyd
- 图论算法(二)-最短路径的Dijkstra [ 单源 ] 和Floyd[ 多源 ] 解法(JAVA )
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- C++实现矩阵图的遍历·最小生成树(prim,kruskal)·最短路径(Dijkstra,floyd)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- 最小生成树(prime算法、kruskal算法) 和 最短路径算法(floyd、dijkstra)
- hdu 2066一个人的旅行(多源最短路径Floyd)