最短パス
説明:
任意シーク図2頂点間の最短経路。
入力:
入力データの最初の行は、nグラフにおける頂点の数を表す正の整数である(頂点それぞれ0,1、...、N-1の番号のために)。N含有nは整数各行後行、第i行とjは2つの頂点間の無限大を表す10,000と、頂点I-1の数と頂点1つのJ-間の側を意味します。2で処理された最短経路の頂点であり、各ライン番号は-1 -1の入力端を示した後に、-1-1解決しません。
出力:
頂点番号の出力シーケンスは、空間頂点によって分離された順序に従って、第二の出力線の最短経路の2つの頂点間の最短経路の長さの第1の出力ライン:各最短経路の頂点は、2本の出力データラインを扱います。2つの頂点、ライン上にのみ出力列「NO」との間にパスが存在しない場合。
例入力
7
0 12 10000 10000 10000 10000 10000
12 0 10000 10000 3 10000 10000
10000 10000 10000 10000 0 21 11
10000 10000 10000 0 10000 10000 10000
10000 3 10000 10000 10000 0 8
10000 10000 21 10000 10000 0 10000
10000 10000 11 10000 8 10000 0
0 2
0 3
5 0
2 1
1 5
-1 -1
サンプル出力
34
0 1 4 6 2
NO
55
5 2 6 4 1 0
22
2 6 4 1
43
1 4 6 2 5
ヒント:あなたはフロイドのアルゴリズムを使用することができ、あなたはまた、ダイクストラアルゴリズム外循環の層を追加することができます。
する#include <stdio.hに> する#include <STDLIB.H> の#define INF 100 の#define MAXV 100 のtypedef構造体{ int型のエッジ[MAXV] [MAXV]。 int型N、E。 } MatGraph。 ボイドフロイド(MatGraph * G、INT A [] [MAXV]、INTパス[MAXV] [MAXV]) { int型I、J、K。 以下のための(I = 0、I <G-> N; I ++) { ため(J = 0; J <G-> nであり、j ++) { A [I] [J] = G->エッジ[I] [J] ; IF(G->エッジ[I] [J] <INF) 経路[I] [J] = J。 他の パス[I] [J] = -1; } } (k = 0; K <G-> nであり、k ++)のための { (iは0 = I ++; I <G-> N)のために { (j = 0; J <G-> N; J ++)のために IF(A [i]が[K] + A [K] [J] <A [I] [J]) { A [I] [J] = A [i]が[K] + A [K] [J] ; 経路[I] [J] =パス[I] [K]。 } } } } } int型のmain() { int型I、J、K。 整数M、N。 INT A [MAXV] [MAXV]。 INTパス[MAXV] [MAXV]。 MatGraph * G =(MatGraph *)はmalloc(はsizeof(MatGraph))。 scanf関数( "%d個"、&G-> N)。 (I ++; I <G-> N I = 0)するための { (; J <G-> N J ++ J = 0)のため のscanf( "%dの"、およびG->エッジ[I] [J])。 } フロイド(G、A、パス); (;;)のために { scanf関数( "%D%D"、&M、&N)。 IF(M == -1 && K =パス[M] [N]。 もし(K <0) { のprintf( "NO \ n"); 持続する; } のprintf( "%D \ n"は、A [m]は[N])。 printf( "%dの"、M)。 一方、(!K = N) { のprintf( "%dの"、K)。 K =パス[K] [N]。 } のprintf( "%d個"、N) printf( "\ n"は); } 0を返します。 }