まず、最短を見ることは難しいことではありません
次に起点、二つの端点。
Dijが小さいものを選択し、フィニッシュから両者を比較するための出発点から側を実行し、その後、一端に出発点として、実行Dijと、ANSプラスもう一方の端までの距離、すなわち、最終的な結果です。
書式#include <iostreamの> の#include <cstdioを> する#include <キュー> の#include <CStringの> 使用して 名前空間はstd; 構造体ノード{ INT に、NXT、DIS。 } E [ 400010 ]。 構造体のエッジ{ int型のVal、NM。 ブール 演算子 <(constのエッジ&X)のconst { 戻り値> x.valと、 } }。 PRIORITY_QUEUE <エッジ> をDij。 int型のヘッド[ 100001 ]、中 [ 100001]、D [ 100001 ]。 int型のCNT; INTのN、M、S1、S2、S3。 インラインint型リード(){ int型、S = 0、W = 1 。 チャー CH = GETCHAR()。 一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ' = W) - 1 ; CH = GETCHAR();} 一方(CH> = ' 0 ' && CH <= ' 9 '){S = sの* 10 + CH- '0 ' ; CH = GETCHAR();} 戻り S * W。 } インラインボイド追加(INT から、INTに、int型のDIS){ E [ ++ CNT] =(ノード){[ヘッドへのDIS、]}。 【ヘッドから =] CNT。 } インラインボイドジ(int型の){ ため(int型 iは= 1 ; iは= N <; ++ I)D [i]は= 2147483647 。 memsetの(中、0、はsizeof(中)); dij.push((エッジ){ 0 、S})。 D [S] = 0 ; 一方、(!dij.empty()){ int型、T = 。dij.top()NM。 dij.pop(); もし(で [T])続けます。 で [T] = 1 。 用(int型 I =ヘッド[T];!i = 0 ; i = E [I] .nxt){ 場合(!における [E [i]の.TO] && D [T] + E [i]は.DIS < D [E [I] .TO]){ D [E [i]は.TO] = D [T] + E [I] .DIS。 dij.push((エッジ){D [E [i]の.TO]、E [I] .TO})。 } } } } int型のmain(){ scanf関数(" %D%D%D%D%D "、&M、&N、&S1、およびS2、およびS3)。 INT X、Y、Z。 以下のために(int型 I = 1 ; I <= M; ++ I){ scanf関数(" %D%D%D "、およびX&Y、およびZ)。 (X、Y、Z)を追加し、(X、Y、Z)を追加します。 } ジ(S1)。 INT ANS = 分(D [S2]、D [S3])。 ジ(S2)。 ANS + = D [S3]。 printf("%のD 」、年); 0 ; }