说实话,在一开始没学的时候还觉得挺高大上的算法,学了之后发现,最短路四大算法,这是最暴力的一个。。

Floyd-Warshall算法,一般也叫Floyd算法,这个算法正如网传的那样:核心算法只有5行:

for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) for(int k = 1; k <= n; k++) if(dis[j][k] > dis[j][i] + dia[i][k])
 dis[j][k] = dis[j][i] + dia[i][k];

(话说光是看那三个for就觉得有够暴力了阿喂。。。。。

该算法基本思想只有一个:如果从一个点到另一个点的直接路径不是最短的,那最短路肯定要经过第三个点。所以就用所有的点都当一次中间点,来判断是不是任意两点之间经过中间点路程会减小。

示例代码:

typedef long long LL;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
using namespace std;

int pre[MAXN + 3][MAXN + 3], dist[MAXN + 3][MAXN + 3]; //pre 储存路径; dist 存储最短距离
void floyd(int n, int gra[][MAXN + 3]) {
    for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) dist[i][j] = gra[i][j], pre[i][j] = j;  //初始化
    for(int k = 1; k <= n; k++) {   //尝试经过 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[i][k];
                }
            }
        }
    }
}

int pfpath(int u, int v) { //打印最短路径
    while(u != v) {
        cout << u  << " ";
        u = pre[u][v];
    }
    cout << u << endl;
}

int gra[MAXN + 3][MAXN + 3];
int main() {
    int n, m;
    while(cin >> n >> m){ // n 个点, m 条边
        for(int i = 0; i <= n; i++) for(int j = -1; j <= n; j++){
            gra[i][j] = (i == j ? 0 : INF);
        }
        for(int i = 0; i < m; i++) {
            int u, v, w; cin >> u >> v >> w;
            gra[u][v] = gra[v][u] = w;  //无向图
        }
        floyd(n, gra);
    }
    return 0;
}