Floyd-Warshall算法

  Floyd也是采用动态规划的方案来解决在一个有向图G=(V,E)上每对顶点间的最短路径问题。运行时间为Θ(V3)。

算法分析:

  用邻接矩阵map[][]存储有向图,用dist[i][j]表示i到j的最短路径。设G的顶点为V={1,2,3...n},对于任意一对顶点i,j属于V,假设i到j有路径且中间节点皆属于集合{1,2,3...k},P是其中的一条最小权值路径。就是i到j的最短路径P所通过的中间顶点最大不超过k。

  设为从的只以集合中的节点为中间节点的最短路径的长度。

  1. 若最短路径经过点k,则
  2. 若最短路径不经过点k,则

  因此,

for k ← 1 to n do
  for i ← 1 to n do
    for j ← 1 to n do
      if (Di,k + Dk,j < Di,j) then
         Di,j←Di,k + Dk,j ;

实现代码:

/*************************************************************************
    > File Name: Floyd_Warshall.cpp
    > Author: He Xingjie
    > Mail: [email protected]
    > Created Time: 2014年06月12日 星期四 15时57分22秒
    > Description:
 ************************************************************************/
#include<iostream>
#include<cstdio>
using namespace std;

#define MAX 20
#define INF 65535

//map邻接矩阵,dist记录最短路径,path用于最短路径
int map[MAX][MAX], dist[MAX][MAX], path[MAX][MAX];

int Init()
{
    int n;

    cin>>n;
    for (int i=0; i<n; i++)
        for(int j=0; j<n; j++)
        {
            cin>>map[i][j];
            dist[i][j] = map[i][j];
            path[i][j] = 0;
        }

    return n;
}

void Floyd(int n)
{
    int i, j, k;

    for (k=0; k<n; k++)
        for (i=0; i<n; i++)
            for (j=0; j<n; j++)
                if (dist[i][k] != INF && dist[k][j] !=INF
                        && dist[i][j] > dist[i][k] + dist[k][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = k;        //i到j要经过K节点
                }
}

void PrintShortestPath(int i, int j)
{
    //递归打印最短路径

    if (path[i][j] == 0)    //表示i->j没有中间节点
    {
        printf("%d ", j+1);
        return;
    }
    else
    {
        PrintShortestPath(i, path[i][j]);
        PrintShortestPath(path[i][j], j);
    }
}

void PrintMap(int n)
{
    int i, j;

    for    (i=0; i<n; i++)
    {
        for (j=0; j<n; j++)
            cout<<dist[i][j]<<" ";
        cout<<endl;
    }
    cout<<endl;
}

int main()
{
    int n;

    freopen("input.txt", "r", stdin);
    n = Init();
    Floyd(n);
    PrintMap(n);

    for (int i=0; i<n; i++)
    {
        for (int j=0; j<n; j++)
        {
            if (i != j)
            {
                cout<<i+1<<" ";
                PrintShortestPath(i, j);
                cout<<endl;
            }
        }
        cout<<endl;
    }
    return 0;
}

2014/6/13  23:24

 输入数据:

5
0 3 8 65535 -4
655535 0 65535 1 7
65535 4 0 65535 65535
2 65535 -5 0 65535
65535 65535 65535 6 0

输出数据:

参考:

http://zh.wikipedia.org/zh/%E5%BC%97%E6%B4%9B%E4%BC%8A%E5%BE%B7%E7%AE%97%E6%B3%95

http://www.cppblog.com/mythit/archive/2009/04/21/80579.aspx

Floyd-Warshall算法

时间: 2024-10-06 16:22:09

Floyd-Warshall算法的相关文章

Floyd最短路径算法

暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表示这条公路的长短.请注意这些公路是单向的.我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径.这个问题这也被称为“多源最短路径”问题. 现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4的矩阵(二维数组e)来存储.比如1号城市到2号城市的路程为2,则设e[1][2]

poj 3660 Cow Contest(warshall算法)

poj 3660 Cow Contest Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming contest. As we all know, some cows code better than others. Each cow has a certain constant skill rating that is unique among the co

uva 125 Numbering Paths(warshall算法)

uva 125 Numbering Paths Description Download as PDF Background Problems that process input and generate a simple yes'' orno" answer are called decision problems. One class of decision problems, the NP-complete problems, are not amenable to general ef

Warshall算法

---用Warshall算法解决传递闭包问题 ---在一个关系R中,如果任意的(a,b)和(b,c)在关系R中,则(a,c)也一定在关系R中,则称R是可传递的.一个关系R的传递闭包是包 含R的最小的传递关系. ---Warshall算法不用来计算最短路径,而是用来判断i和j之间是否单向连接,无论是直接连接还是间接连接 ---初始条件不再是邻接矩阵,而是关系矩阵,如果两个点之间直接单向连接,那么在矩阵中对应的值就为1,反之为0 ---根据已有的直接连接关系得出其它所有的间接连接关系,即判断两点之间

Warshall算法求传递闭包

传递闭包 在数学中,在集合 X 上的二元关系 R 的传递闭包是包含 R 的 X 上的最小的传递关系. 例如,如果 X 是(生或死)人的集合而 R 是关系“为父子”,则 R 的传递闭包是关系“x 是 y 的祖先”.再比如,如果 X 是空港的集合而关系 xRy 为“从空港 x 到空港 y 有直航”,则 R 的传递闭包是“可能经一次或多次航行从 x 飞到 y”. Warshall算法 Warshall在1962年提出了一个求关系的传递闭包的有效算法.其具体过程如下,设在n个元素的有限集上关系R的关系矩

求传递闭包的warshall算法

———————————————————————————— Question:R是定义于集合S上的二元关系,求R的传递闭包. Input:relation R,set A Output:t(R),which is the transitive closure of R  Solution:Warshall algorithm ———————————————————————————— 传递闭包(transitive closure) R* = R1 ∪ R2 ∪ R3 ∪ ...... ∪ Rn  

最小环——Floyd变种算法(C++)

源代码: #include<cstdio>#include<cstring>int n,i[1001][1001],f[1001][1001],ans;int main(){ memset(i,0x3f,sizeof(i)); memset(f,0x3f,sizeof(f)); ans=0x3f; //对于存储变量和数组,初始化为最大值. scanf("%d",&n); for (int a=1;a<=n;a++) for (int b=1;b&l

hdu 1874 畅通工程续 两种算法AC Floyd+Bellman-Ford算法 又是一波水题~~

畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 31655    Accepted Submission(s): 11564 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行

算法:最短路径之弗洛伊德(Floyd)算法

https://cloud.tencent.com/developer/article/1012420 为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例.图7-7-12的左图是一个简单的3个顶点的连通网图. 我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点的最短路径权值和的矩阵.P代表对应顶点的最短路径的前驱矩阵.在未分析任何顶点之前,我们将D命名为D(-1),其实它就是初始图的邻接矩阵.将P命名为P(-1), 初始化为图中的矩阵. 首先我们来分析

Algorithm --&gt; Dijkstra和Floyd最短路径算法

Dijkstra算法 一.最短路径的最优子结构性质 该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径.下面证明该性质的正确性. 假设P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,j).而 P(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径P'(k,s),那么 P'(i,