1. 程式人生 > >數據結構 最短路徑 Floyd 算法

數據結構 最短路徑 Floyd 算法

NPU 成了 can continue 兩個 code 操作 clu mes

Floyd Algorithm

#include<cstdio>
#include<algorithm>
using namespace std;

const int MAXV = 510;       //  最大頂點數 
const int INF = 1000000000;     //  無窮大 
//頂點數,邊數,鄰接矩陣
int V, E, G[MAXV][MAXV];
//A用來記錄當前已經求得的任意兩個頂點最短路徑長度
//Path用來記錄當前兩頂點間最短路徑要經過的中間頂點 
int A[MAXV][MAXV], Path[MAXV][MAXV];

void Floyd(){
    int i, j, k;    
    //  這個雙循環對數組A[][]和Path[]進行了初始化
    for(i = 0; i < V; ++i){
        for(j = 0; j < V; ++j){
            A[i][j] = G[i][j];
            A[i][i] = 0;    //  對角線元素都為 0 
            Path[i][j] = -1;
        }
    }   
    //  下面這個三層循環是本算法的主要操作,完成了以k為中間點對所有頂點對{i,j}進行檢測和修改
    for(k = 0; k < V; ++k){
        for(i = 0; i < V; ++i){
            for(j = 0; j < V; ++j){
                if(A[i][j] > A[i][k] + A[k][j] ){
                    A[i][j] = A[i][k] + A[k][j];
                    Path[i][j] = k;
                }
            }
        }
    }   
}
//打印最短路徑,采用遞歸 
void PrintPath(int u, int v){
    if(Path[u][v] == -1)
        printf("%d ", v);   //  直接輸出 
    else{
        int mid = Path[u][v];
        PrintPath(u, mid);  //  處理 mid 前半段路徑
        PrintPath(mid, v);  //  處理 mid 後半段路徑
    }
}
int main(){
    int a, b;
    scanf("%d %d", &V, &E);
    fill(G[0], G[0] + MAXV * MAXV, INF);    //  初始化圖 
    for(int i = 0; i < E; i++){
        scanf("%d %d", &a, &b);
        scanf("%d", &G[a][b]);  //  讀入邊權
    }
    
    //  查詢 st -> end 的最短路徑 
    int st, end;    //  起點,終點 
    scanf("%d %d", &st, &end);
    
    Floyd();    //  Floyd算法入口
    
    //  打印Floyd算法處理後的Path[][], A[][]數組 
    printf("Path\n");
    for(int i = 0; i < V; i++){
        for(int j = 0; j < V; j++)
            printf("%4d", Path[i][j]);
        printf("\n");
    }
    
    printf("A\n");
    for(int i = 0; i < V; i++){
        for(int j = 0; j < V; j++){
            if(A[i][j] == INF){
                printf("  ∞");
                continue;
            }
            printf("%4d", A[i][j]);
        }   
        printf("\n");
    }
    
    //  輸出查詢結果 
    printf("從%d到%d的路徑:%d ", st, end, st);
    PrintPath(st, end);

    return 0;
}

sample input1:

7 12
0 1 4
0 2 6
0 3 6
1 4 7
1 2 1
3 2 2
3 5 5
2 4 6
2 5 4
5 4 1
4 6 6
5 6 8
0 6

sample output1:

Path
  -1  -1   1  -1   5   2   5
  -1  -1  -1  -1   5   2   5
  -1  -1  -1  -1   5  -1   5
  -1  -1  -1  -1   5  -1   5
  -1  -1  -1  -1  -1  -1  -1
  -1  -1  -1  -1  -1  -1   4
  -1  -1  -1  -1  -1  -1  -1
A
   0   4   5   6  10   9  16
   ∞   0   1   ∞   6   5  12
   ∞   ∞   0   ∞   5   4  11
   ∞   ∞   2   0   6   5  12
   ∞   ∞   ∞   ∞   0   ∞   6
   ∞   ∞   ∞   ∞   1   0   7
   ∞   ∞   ∞   ∞   ∞   ∞   0
從0到6的路徑:0 1 2 5 4 6

sample input2:

4 8
0 3 7
0 1 5
1 2 4
1 3 2
2 0 3
2 1 3
2 3 2
3 2 1
1 0

sample output2:

Path
 -1 -1  3 -1
  3 -1  3 -1
 -1 -1 -1 -1
  2  2 -1 -1
A
  0  5  8  7
  6  0  3  2
  3  3  0  2
  4  4  1  0
從1到0的路徑:1 3 2 0

數據結構 最短路徑 Floyd 算法