タイトルます。https://nanti.jisuanke.com/t/41349
分析:英雄のために、単一ソース最短歩く最短マルチソース、消防士のために、DISの配列を見つけることができる最大値を通過し、その後、歩いて、ちょうど、各火災ポイントを接続するために、スーパーの出発点を構築するために右サイドを必要とします0 spfaはDISアレイに行きます
注:無向エッジを取得
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 constの LL INF = 1E18; const int型 M = 2E3 + 3 ; LLのDIST [M]。 構造体ノード{ int型V、nextt。 ワットLL; } E [(Mの *のM)<< 1 ]。 INTのTOT、VIS [M]、ヘッド[M]、[M]、署名[M]。 ボイド addedge(int型 U、int型V、LLのW){ E [TOT] .V = V。 E [TOT] .nextt = 頭部[U]。 E [TOT] .W = W。 ヘッド[U]は ++ TOTを= 。 } ボイド spfa(INT S) { キュー < INT > Q。 しばらく(!q.empty()) q.pop(); memset(DIST、0x7Fを、はsizeofのDIST)。 // COUT << DIST [0] << ENDL。 memsetの(VIS、偽、はsizeof VIS)。 DIST [S] = 0 ; VIS [S] = 真。 q.push(S); しばらく(!q.empty()){ int型のu = q.front(); q.pop(); VIS [U] = 偽; 用(int型 ;〜I; I =ヘッド[U] I = E [I] .nextt){ int型、V = E [I] .V。 もし(DIST [V]> DIST [U] + E [I] .W){ DIST [V] = DIST [U] + E [I] .W。 もし(!VIS [V]){ VIS [V] = 真; q.push(V); } } } } } int型のmain(){ int型のT。 のscanf("%のD "、&T)。 一方、(t-- ){ int型 N、M、彼は、K、C、S = 0 。 scanf関数(" %D%D%D%D%D "、&N、&M、&彼、&K&C); 用(int型 I = 0 ; iが<= N; iが++ ) ヘッド[I] = - 1、[I] =署名0 。 TOT = 0 ; 用(int型 i = 1 ; iが= Kを<Iは++ ) のscanf(" %dの"、&[i])と、署名[[I] = 1 。 一方、(M-- ){ int型Uを、V。 ワットLL; scanf関数(" %D%D%LLD "、&U&V、およびW) addedge(U、V、W)。 addedge(V、U、W)。 } spfa(彼)。 LL maxxhe = 0LL。 用(int型 i = 1 ; iが<= N; iが++ ) maxxhe = MAX(maxxhe、DIST [I])。 用(int型 i = 1 ; iが= Kを<Iは++ ) addedge(S [i]は、 0 ); spfa(S); LL maxxren = 0LL。 以下のために(int型 i = 1 ; iは= N <; iは++ ){ 場合(ログイン[I] == 0 ) maxxren = MAX(DIST [I]、maxxren)。 } maxxren * = 1LL * C。 // coutの<< maxxhe << "!!" << maxxren <<てendl; もし(maxxhe <= maxxren){ のprintf(" %LLDする\ n " 、maxxhe)。 } 他 のprintf(" %LLDする\ n "、maxxren / C)。 } 戻り 0 。 }