(任意两点间最短路)Floyd-Warshall算法

Floyd-Warshall算法使用DP方法来求解任意两点间的最短路问题。
i到j的最短路分正好经过顶点k一次和完全不经过顶点k两种情况来讨论。不断的进行d[i][j] = min(d[i][j], d[i][k] + d[k][j])的更新来实现,复杂度是O(n ^ 3)。
此算法可以处理负权边,也可以判断图中是否有负圈,只需检查是否存在d[i][i]是负数的顶点i就可以了。

//Floyd-Warshall
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int
MAXV = 105, MAXE = 10005, INF = 0x3f3f3f3f;

int v, e;
int d[MAXV][MAXV];

bool Floyd_Warshall() {
    for(int k = 1; k <= v; ++k) {
        for(int i = 1; i <=v; ++i) {
            for(int j = 1; j<= v; ++j) {
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
            }
        }
    }
    for(int i = 1; i <= v; ++i) 
        if(d[i][i] < 0)
            return false;
    return true; 
}
int main() {
    while(scanf("%d%d", &v, &e) != EOF && v && e) {
        for(int i = 1; i <= v; ++i) {
            for(int j = 1; j <= v; ++j) {
                d[i][j] = d[j][i] = (i == j ? 0 : INF);
            }
        }
        for(int i = 1; i <= e; ++i) {
            int f, t, c;
            scanf("%d%d%d",&f, &t, &c);
            d[f][t] = d[t][f] = c;
        }
        if(Floyd_Warshall())
            printf("%d\n", d[1][v]);
        else
            printf("有负圈\n");
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 归去来兮。 1.1 说明 本篇为《挑战程序设计竞赛(第2版)》[http://www.ituring.com.cn...
    尤汐Yogy阅读 14,451评论 0 160
  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,771评论 0 33
  • 动态规划(Dynamic Programming) 本文包括: 动态规划定义 状态转移方程 动态规划算法步骤 最长...
    廖少少阅读 3,336评论 0 18
  • 本文将介绍三种常见的最短路算法:Dijkstra,Floyd,SPFA Dijkstra Dijkstra是有向图...
    maxkibble阅读 1,538评论 0 0
  • Floyd 算法 简介 Floyd 算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径...
    廖少少阅读 8,669评论 0 1