任意两点间的最短路问题 Floyd-Warshall算法

这一算法与之前的Bellman-F=Ford算法一样,都可以判断负环

只需要检查dp [i] [j] 是负数的顶点i即可

 1 // 求解任意两点间的最短路径问题
 2 // Floyed-Warshall算法
 3 // 复杂度O(N^3),N为顶点数
 4
 5 #include <cstdio>
 6 #include <iostream>
 7
 8 using namespace std;
 9 // 用dp的思路来求解
10 // dp[k][i][j]:从i到j,只利用前K个节点的最短路
11 // dp[k][i][j]=dp[k-1][i][k] + dp[k-1][k][j]
12 // 由于后一层所需的,都来自前一层,而前一层所需
13 // 然后在考虑循环顺序,定k,并且维护最小,所以中间元素必定使用之前维护的在k行k列的元素
14 // 而维护最小值时,k行k列元素,在循环中,加和一定大于原来的值(否则存在d[i][j]<0,存在负圈)
15 // 所以维护最小值时不更新,依旧是上一列表中的值
16 // 所以dp数组可以降维进行运算
17
18 const int max_N = 200+2;
19 const int max_E = 10000+2;
20 const int INF = 1e9;
21
22 int dp[max_N][max_N];
23 int N,E;
24
25 void floyd_warshall()
26 {
27     for(int k=0;k<N;++k)
28     {
29         for(int i=0;i<N;++i)
30         {
31             for(int j=0;j<N;++j)
32             {
33                 dp[i][j]=min( dp[i][j],dp[i][k]+dp[k][j] );
34             }
35         }
36     }
37 }
38
39 int main()
40 {
41     scanf("%d %d",&N,&E);
42     int a,b,c;
43     for(int i=0;i<N;++i)
44     {
45         for(int j=0;j<N;++j)
46         {
47             if(i==j)
48             {
49                 dp[i][j]=0;
50             }
51             else
52             {
53                 dp[i][j]=INF;
54             }
55         }
56     }
57     for(int i=0;i<E;++i)
58     {
59         scanf("%d %d %d",&a,&b,&c);
60         dp[a][b]=c;
61         // 无向图
62         dp[b][a]=c;
63     }
64     floyd_warshall();
65
66     for(int i=0;i<N;++i)
67     {
68         for(int j=0;j<N;++j)
69         {
70             printf("%d ",dp[i][j]);
71         }
72         printf("\n");
73     }
74     return 0;
75 }
76 /*
77 7 10
78 0 1 2
79 0 2 5
80 1 2 4
81 1 3 6
82 1 4 10
83 2 3 2
84 3 5 1
85 4 5 3
86 4 6 5
87 5 6 9
88
89
90
91
92 0 2 5 7 11 8 16
93 2 0 4 6 10 7 15
94 5 4 0 2 6 3 11
95 7 6 2 0 4 1 9
96 11 10 6 4 0 3 5
97 8 7 3 1 3 0 8
98 16 15 11 9 5 8 0
99 */

原文地址:https://www.cnblogs.com/jishuren/p/12318080.html

时间: 2024-08-11 16:37:17

任意两点间的最短路问题 Floyd-Warshall算法的相关文章

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

1 #define _CRT_SECURE_NO_WARNINGS 2 /* 3 7 10 4 0 1 5 5 0 2 2 6 1 2 4 7 1 3 2 8 2 3 6 9 2 4 10 10 3 5 1 11 4 5 3 12 4 6 5 13 5 6 9 14 0 6 15 */ 16 #include <iostream> 17 #include <vector> 18 #include <utility> 19 #include <queue> 2

Floyd-Warshall算法(求解任意两点间的最短路) 详解 + 变形 之 poj 2253 Frogger

/* 好久没有做有关图论的题了,复习一下. --------------------------------------------------------- 任意两点间的最短路(Floyd-Warshall算法) 动态规划: dp[k][i][j] := 节点i可以通过编号1,2...k的节点到达j节点的最短路径. 使用1,2...k的节点,可以分为以下两种情况来讨论: (1)i到j的最短路正好经过节点k一次 dp[k-1][i][k] + dp[k-1][k][j] (2)i到j的最短路完全

图论之最短路02-2——改进的任意两点间最短距离及路径

======================================================== 重要程度 ***** 求任意两点间最短距离及其路径.(万能最短路) 输入:权值矩阵,起点,终点 输出:最短距离矩阵,指定起讫点路径(经过的顶点编号) ======================================================== function renyizuiduanlu(W) clc disp('                        

基于pgrouting的任意两点间的最短路径查询函数二

在前面的博文中写过一篇查询任意两点间最短路径的函数,当时对pgrouting不熟悉,功能很low.现在对该函数进行扩展,支持用户自己输入查询的数据库表,这一点看似简单,其实意义很大,在做室内导航的时候当用户所在的楼层变化的时候最短路径函数查询的数据表名称也会发生变化,不可能一栋大楼里的道路都是一样的吧,另外进行跨楼层的最短路径规划时,需要查询从A到楼梯口的最短路径和楼梯口到B的最短路径,这些都需要进行最短路径规划的时候能够自己选择数据表. DROP FUNCTION pgr_fromAtoB(t

基于pgrouting的任意两点间的最短路径查询函数

前面文章介绍了如何利用postgresql创建空间数据库,建立空间索引和进行路径规划.但是在真实的场景中用户进行路径规划的时候都是基于经纬度数据进行路径规划的,因为用户根本不会知道道路上节点的ID.因此文本讲述如何查询任意两点间的最短路径. 一.定义函数名及函数参数 函数名定义为: pgr_fromAtoB 参数设置分别为: 输入为数据库表名,起点和终点的经纬度坐标 输出为:路段序号,gid号,道路名,消耗及道路集合体. IN tbl varchar, --数据库表名 IN x1 double

两点间所有路径的遍历算法

转自:http://blog.sina.com.cn/s/blog_5ff8e88e01013lot.html 这几天,用到了这个功能,但在网上找到了一份资料,思路写的很清晰,但代码有错误.因此,我就按着这个思路,自己整理了代码,现在说明如下:(引用前部分思想,更新后部分代码) 两点间所有路径的遍历算法 中国海洋大学 信息科学与工程学院 熊建设 梁磊 摘要:本文首先简单介绍图的深度优先遍历算法,接着根据图的深度优先遍历算法求出连通图中两点间所有路径,并给出代码. 关键词:图.深度优先遍历.算法

图论之最短路02-1——任意两点间最短距离及路径

======================================================== 求任意两点间最短距离及其路径.(万能最短路) 输入:权值矩阵,起点,终点 输出:最短距离矩阵,指定起讫点路径(经过的顶点编号) 为任意一点到其他点最短路奠定基础 ======================================================== function [P d]=liangdianzuiduanlu(W,qidian,zhongdian) W

任意两点间的最短路 Floyd及其本质

我们知道在已知起点的情况下,求到其他任何一点的最短路是用dijkstra,那么在一个有向图中,我们想知道任意两点之间的最短路,我们就可以使用floyd,而且这个算法表面看起来非常的简单,就是一个三重循环,如果这个图有N个点,那么复杂度为O(|N|3),代码如下. 1 for(int k=0;k<n;k++) 2 for(int i=0;i<n;i++) 3 for(int j=0;j<n;j++) 4 d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 在复杂度这

任意两点间最短距离floyd-warshall ---- POJ 2139 Six Degrees of Cowvin Bacon

floyd-warshall算法 通过dp思想 求任意两点之间最短距离 重复利用数组实现方式dist[i][j] i - j的最短距离 for(int k = 1; k <= N; k++) for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) dist[i][j] = min(dist[i][j], dist[i][k]+dist[k][j]); 非常好实现 O(V^3) 这里贴一道刚好用到的题 http://poj.org