1. 程式人生 > >一本通網站 1378:最短路徑(shopth)

一本通網站 1378:最短路徑(shopth)

gif sso 路徑 oier 連通 con () algo 如果

【題目描述】

給出一個有向圖G=(V, E),和一個源點v0∈V,請寫一個程序輸出v0和圖G中其它頂點的最短路徑。只要所有的有向環權值和都是正的,我們就允許圖的邊有負值。頂點的標號從1到n(n為圖G的頂點數)。

【輸入】

第1行:一個正數n(2≤n≤80),表示圖G的頂點總數。

第2行:一個整數,表示源點v0(v0∈V,v0可以是圖G中任意一個頂點)。

第3至第n+2行,用一個鄰接矩陣W給出了這個圖。

【輸出】

共包含n-1行,按照頂點編號從小到大的順序,每行輸出源點v0到一個頂點的最短距離。每行的具體格式參照樣例。

【輸入樣例】

5
1
0 2 - - 10
- 0 3 - 7
- - 0 4 -
- - - 0 5
- - 6 - 0

【輸出樣例】

(1 -> 2) = 2
(1 -> 3) = 5
(1 -> 4) = 9
(1 -> 5) = 9

【提示】

樣例所對應的圖如下:

技術分享圖片

嗯~一個簡單的Floyed應用題,正好練練手

Floyd算法

1.定義概覽

Floyd-Warshall算法(Floyd-Warshall algorithm)是解決任意兩點間的最短路徑的一種算法,可以正確處理有向圖或負權的最短路徑問題,同時也被用於計算有向圖的傳遞閉包。Floyd-Warshall算法的時間復雜度為O(N3),空間復雜度為O(N2)。

2.算法描述

算法思想原理:

Floyd算法是一個經典的動態規劃算法。用通俗的語言來描述的話,首先我們的目標是尋找從點i到點j的最短路徑。從動態規劃的角度看問題,我們需要為這個目標重新做一個詮釋(這個詮釋正是動態規劃最富創造力的精華所在)

從任意節點i到任意節點j的最短路徑不外乎2種可能,1是直接從i到j,2是從i經過若幹個節點k到j。所以,我們假設Dis(i,j)為節點u到節點v的最短路徑的距離,對於每一個節點k,我們檢查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,證明從i到k再到j的路徑比i直接到j的路徑短,我們便設置Dis(i,j) = Dis(i,k) + Dis(k,j),這樣一來,當我們遍歷完所有節點k,Dis(i,j)中記錄的便是i到j的最短路徑的距離。

我們可以開一個n*n的鄰接矩陣,記錄聯通情況:f[i][j]如果為1,則說明i到j聯通;如果為∞,則說明不連通(之所以用∞的原因是比較的時候無窮大一定比任何除無窮大以外的數的和都大,這樣就不會把∞算進去),然後可以進一步將f[i][j]=1的地方利用兩點間距離公式將1換成具體的距離

簡單說一下思路:

根據題目給出的鄰接矩陣,利用Floyd算法求出各個點間的最短路徑,然後挨個輸出所求點到每個點的最短路徑,代碼如下:

#include<iostream>
#include<cstdio>
using namespace std;
int n,x,a[100][100];                           //a數組存放鄰接矩陣 
int ch;
const int maxn=0x3f3f3f3f;                     //給定一個很大的數,表示兩點間不連通 
int main()
{
    cin>>n>>x;
    for(int i=1;i<=n;i++)
       for(int j=1;j<=n;j++)
       {
           if(scanf("%d",&ch)) a[i][j]=ch;       //如果輸入合法,則賦值給a[i][j],0也包含 
           else a[i][j]=maxn;                    //如果不合法,說明不連通,賦值maxn 
       }
    for(int k=1;k<=n;k++)                     //Floyd算法 
       for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
             if(i!=j&&j!=k&&k!=i&&(a[i][j]>a[i][k]+a[k][j]))
                a[i][j]=a[i][k]+a[k][j];      //更新最短路 
    for(int i=1;i<=n;i++)
    {
        if(i!=x)
        {
            cout<<"("<<x<<" -> "<<i<<") = "<<a[x][i]<<endl;     //輸出到其他點的最短路 
        }
    }
    return 0;
}

一本通網站 1378:最短路徑(shopth)