問題の解決策
そうXY <= Z xが大きい最大比y Zを表します。
もし<= K1、CB <= K2 、CA <= K3のBA、 どのくらいまで続いCA?明らかに(K1 + K2、K3)をminに等しくなければなりません 。図は、次の図(図醜いWuguai良好ではない)で表されます
C ++ヒープ最適化されたコード
// 図StarRam +ダイクストラ最適化されたスタックにフロントチェーン <入出力ストリーム>の#includeを する#include <cstdioを> する#include <キュー> の#include <CStringの> 使用して 名前空間、STD のconst INT MAX = 100005 ; CONST INT MAXN = 400009 ; CONST INT INF = 0x3f3f3f3f ; int型のヘッド[MAX]、CNT = 0 ; int型T、N-、A、B、LEN; int型DIST [MAX]; BOOL VIS [MAX]; 構造体のエッジ{ // チェーン前星に int型次回、ヴァル、へ。 }エッジ[MAXN]。 インラインボイドは(追加INT U、INT V、INT W) { エッジ[CNT] .TO = V。 エッジ[CNT] .val = W。 エッジ[CNT] .next = 頭部[U]。 ヘッド[U] = CNT ++ 。 } 構造体ノード { int型の POS、DIST。 // 点的位置及距离 ノード(){} ノード(INT P、INT D) { POS = P。 DIST =D; } ブール 演算子 <(constのノード&RHS)CONST // 重载< { 戻り DIST> rhs.dist。 } }。 ボイドをDij(INT 開始) { PRIORITY_QUEUE <ノード> QUE。 以下のために(int型 I = 1 ; I <= T; iは++ ) { DIST [I] = INF。 VIS [i]は = 偽; } DIST [開始] = 0 ; que.push(ノード(開始、0 )); ながら(!Que.empty()) { ノードTEMP = que.top(); // 配列要素とDISTの最小値が率いるプライオリティキュー que.pop(); int型 V = temp.pos; / / 最小値をフィルタリングする 場合(VIS [V])続行 ; // 最小値が検出されたかどうか、それがスキップされる決定 VISを[V] = trueに、 のために(int型 I =ヘッド[V];!I = - 1。エッジ= I [I]は.next) // 尾の更新の最小距離のエッジ点として使用される { int型へ= エッジ[I] .TO、 IF(DIST [に対する]> DIST [V] + エッジ[I] .val) { [に対する] DIST = DIST [V] + エッジ[I] .val。 que.push(ノード(DIST、へ)へ])。 } } } } int型のmain() { 一方(のscanf(" %d個の%のD "、&T&N)=!EOF) { memsetの(頭、 - 1、はsizeof (ヘッド))。 以下のために(int型 i = 0 ; iがn <; iは++ ) { scanf関数を(" %D%D%D "、&、&B、&LEN)。 (A、B、LEN)を加えます。 // (B、LEN)を追加します。 } をDij(1 )。 printf(" %d個の\ n " 、DIST [T])。 } 戻り 0 。 }
C ++ペアリングヒープの最適化
#include <ビット/ STDC ++ H> の#include <EXT / pb_ds / priority_queue.hpp> 使用して 名前空間STD。 使用して 名前空間の__gnu_pbdsを。 typedefのペア < int型、int型 > PII。 typedefの__gnu_pbds :: PRIORITY_QUEUE <PII、大きい<PII>、pairing_heap_tag> ヒープ。 const int型 MAXN = 1E5 + 10 。 const int型 INF = 0x3f3f3f3f 。 INTのN、M、S。 構造体のエッジ{ int型U、V、W。 エッジ(int型 _u = 0、INT_V = 0、INT _W = 0){= W U = _U、V = _V、_w;} }。 ベクトル <エッジ> E; ベクター < INT > G [MAXN]。 ボイド addedge(int型 U、int型 V、INT W) { E.push_back(エッジ(U、V、W))。 G [U] .push_back(E.size() - 1 )。 } INT D [MAXN]。 ボイドダイクストラ() { memsetの(D、0x3fを、はsizeof (d)参照)。 ヒープQ; ヒープ:: point_iterator番号[MAXN]。 D [S] = 0 ; ID [S] = Q.push(make_pair(D [s]は、S))。 一方、(!Q.empty()) { int型、U = Q.top()は、第2。Q.pop(); 以下のために(int型 i = 0 ; iは、Gを<U] .size(); iは++ ) { エッジ&E = E [G [U] [I]]。int型の V = EV。 もし(dは[V]> D [U] + EW) { D [V] Dは= [U] + EW。 もし(!ID [V] = 0 )Q.modify(ID [V]、make_pair(D [V]、V))。 他 ID [V] = Q.push(make_pair(D [V]、V))。 } } } } int型のmain() { ながら(〜のscanf(" %D%dの"、&N、&M)){ S = 1。// 起点 // のmemset(D、0、はsizeofのD)。 memsetの(G、0、はsizeof G)。 以下のために(int型 I = 1 ; I <= M; iは++ ) { int型、U、V、W。 scanf関数(" %D%D%D "、&uは、&V、& W) addedge(U、V、W)。 } ダイクストラ()。 // (I = 1をint型、iが<= N; iが++)のためのprintf( "%D%s"は、D [i]は、((I == N) "\ n"は?」「)); printf(" %d個の\ n " 、D [N])。 } }