Folyd算法求最短路
介绍:
Folyd算法是用来求带权图中每两点之间的最短路的动态规划算法,(它每次求得的值都可以在后面使用)。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。
算法思想:
要从节点i走到j总的来说只有两种办法,一种是直接从i到j,不途径任何节点;另一种是经过若干个中间节点k到达j。有时候走“直路”的距离不一定会比走“弯路”的距离要短,所以,我们要做的就是要检查在i,j之间插入其他节点能否让他们之间的路径变短。
算法描述:
- 对结点数为n的图,初始化S为表示图中每两点距离的矩阵,令k=1;
- 依次检查S中的每两个结点u,v之间的距离dis(u,v),在插入了k之后会不会变短。若变短,则更新他们之间的距离,即令dis(u,v)=dis(u,k)+dis(k,v);
- k+1,重复2,3步骤,直到k=n。
特点:
这个算法写起来很简单,和Dijkstra算法比起来,它能很方便的求出图中每两点之间的距离,但是由于它需要使用三个循环来遍历各种插入的情况,所以在结点数比较多的时候会比较耗时。
C++实现:
#include<iostream> using namespace std; #define MAX 100 #define INF 100000 int G[MAX][MAX]; int main() { int n, m; //n是结点数,不超过100,m是边数 int u, v,w; //[u,v]结点,w是权重 cin >> n >> m; for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { G[i][j] = INF; if (i == j) { G[i][j] = 0; } } } for (int i = 0; i < m; i++) { cin >> u >> v>> w; G[u - 1][v - 1] = w; } for (int k = 0; k < n; k++){ for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (G[i][k]+G[k][j]<G[i][j]) { G[i][j] = G[i][k] + G[k][j]; } } } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (G[i][j] != INF&&i!=j) { cout << i+1 << "->" << j+1 << " " << G[i][j] << endl; } } } system("pause"); }