Floyd-Warshall算法

  Floyd也是採用動態規劃的方案來解決在一個有向圖G=(V,E)上每對頂點間的最短路徑問題。運行時間爲Θ(V3)。ios

算法分析:算法

  用鄰接矩陣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。spa

  D_{i,j,k}爲從ij的只以(1..k)集合中的節點爲中間節點的最短路徑的長度。code

  1. 若最短路徑通過點k,則D_{i,j,k}=D_{i,k,k-1}+D_{k,j,k-1}
  2. 若最短路徑不通過點k,則D_{i,j,k}=D_{i,j,k-1}

  所以,D_{i,j,k}=\mbox{min}(D_{i,k,k-1}+D_{k,j,k-1},D_{i,j,k-1})blog

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: gxmshxj@163.com
    > 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  2324

 輸入數據:ip

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

輸出數據:ci

 

參考:get

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

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

相關文章
相關標籤/搜索