問題解決のアイデアを:ダイクストラアルゴリズムの使用は、一度最短時間をカウントし、二回数え、最短パス最初の計算、パスを開くために別のレコードの配列
する#include <stdio.hに> する#include < 文字列・H> に#define INF 0x3f3f3f3f の#define MaxVex 500 のtypedef 構造体{ int型の長さ; int型の時間; }グラフ、 グラフG [MaxVex] [MaxVex]; // 図 INT訪問[MaxVex ] = { 0 }; // アクセスタグ のint FPATH [MaxVex]; // 最速ルート のint LPATH [MaxVex]; // 最短パス INT NUM [MaxVex] = { 0 }; // ノードカウント INT NV、数Ne。 //图初始化-邻接矩阵 ボイドは、init(){ int型I、J。 以下のために(私は= 0 ; I <ネバダ州; iは++ ){ ため(J = 0 ; J <Nvの、J ++ ){ G [I] [J] .LENGTH = INF。 G [I] [J] .time = INF。 } } int値V1、V2、ONE_WAY、長さ、時間。 以下のために(私は= 0 ; I <Neは、I ++ ){ scanf関数は(" %D%D%D%D%D "、&V1&V2&ONE_WAY、・長さ、及び時間)。 G [V1] [V2] .LENGTH = 長さ。 G [V1] [V2] .time =時間; IF(!ONE_WAY){ G [V2] [V1] = G [V1]、[V2]; } } } 無効ダイクストラ(int型の S、INT 型){ 訪問[S] = 1。; NUM [S] = 1 ; INT I、J、W、MIN; //は、最速ルートを計算し、最速ルートならないユニークが、最短経路が選択される IF(タイプ== 1。{) のために、私は=(0を ; I <Nvは、I ++ ){ MIN = INF; のため(J =0 ; J <のNv、J ++){ もし!(訪問[J] && G [S] [J] .time < MIN){ MIN = G [S] [J] .time。 W = J; } } 訪問[W] = 1 。 用(J = 0 ; J <Nvの、J ++ ){ 場合(!訪問[J] && MIN + G [J] [W] .time < G [S] [J] .time){ G [S] [J] .time = MIN + G [J] [W] .time。 FPATH [J] = W。 } それ以外の 場合(!訪問[J] && MIN + G [W] [J] .time == G [S] [J] .time){ // ここでメモはその最短経路G [W] [J] .LENGTH <G [ FPATH [J] [J] .LENGTH // なくG [S] [W] .LENGTH + G [W] [J] .LENGTH <G [S] [J] .LENGTH IF(G [W] [ J] .LENGTH < G [FPATH [J] [J] .LENGTH){ FPATH [J] = W; } } } } } そう IF(タイプ== 2){ // ない場合にのみ、最短経路を計算し、最初のノードは小さい ため(J = 0 ; J <Nvと; J ++ ){ MIN = INF。 以下のために(私は= 0; I <Nvは、I ++ ){ 場合(訪問[I] && G [S] [I] .LENGTH <!MIN){ MIN = G [S] [I] .LENGTH。 W = I; } } 訪問[W] = 1 。 以下のための(iは= 0 ; I <NvのI ++ ){ 場合(!訪問[I] && MIN + G [W] [I] .LENGTH < G [S] [I] .LENGTH){ G [S] [I] .LENGTH = MIN + G [W] [I] .LENGTH。 LPATH [I] = W。 NUM [I] = NUM + [W] 1 ; } そう IF(!訪問[I] && MIN + G [W] [I] .LENGTH == G [S] [I] .LENGTH){ IF(NUM [W] + 。1 < NUM [I]) { NUM [I] = NUM [W] + 1 ; LPATH [I] = W; } } } } } } //は、2つのパスが同じでないか否かを判断 INT IsTheSame(INT A []、INT N-、int型 B []、INTM){ IF(!N = M) 戻り 0 ; 他の{ int型のI; 以下のために(私は= 0 ; iが<= N; I ++ ){ 場合([I] =!B [i])と リターン 0 。 } を返す 1 。 } } int型のmain(){ scanf関数(" %D%D "、およびNV、&NE)。 初期化(); int型のS、D、I。 scanf関数(" %D%D "、&S&D)。 memsetの(訪問、0、はsizeof (訪問)); のために(私は= 0 ; I <Nvは、I ++ ){ FPATH [I] = S; } ダイクストラ(S、1。); のmemset(訪問、0、はsizeof (訪問)); のための(I = 0 ; I <Nvは、I ++ ){ LPATH [I] = S; } ダイクストラ(S、2 ); // 配列に逆方向出力パス INT F = D、L = D; INT FRoad [MaxVex] = { 0 }、LRoad [MaxVex] = { 0 }; INTT = 0、K = 0 。 一方、(!F = S){ FRoad [T ++] = F。 F = FPATH [F]。 } FRoad [T] = S。 一方、(!L = S){ LRoad [K ++] = L。 L = LPATH [L]。 } LRoad [K] = S。 // 结果输出 場合(IsTheSame(FRoad、T、LRoad、K)){ のprintf(" 時間=%dを、距離=%のD:" 、G [S] [D] .time、G [S] [D] .LENGTH); ため(私は、Tが=; I> = 0 ; i-- ){ のprintf(" %dの" 、FRoad [I])。 もし(I) のprintf(" => " ); } } 他{ のprintf(" 時間=%のD:" 、G [S] [D] .time)。 以下のためには、式(I Tを=; I> = 0 ; i-- ){ のprintf(" %dの" 、FRoad [I])。 もし(I) のprintf(" => " ); printf(" \ n " ); のprintf(" 距離=%D:"G [S] [D] .LENGTH)は、 のために(私はkは=; I> = 0 ; i-- ){ のprintf(" %dの" 、LRoad [I]); もし(I) のprintf(" => " ); } } }