タイトルの意味は右側で、無向グラフに接続され、電力の一定量の下各側面が消費しました。K臨界点が完全に充電することができますがありますが、私は少なくとも、必要な電池容量があり、臨界点から別のキーポイントをお願いしに行きました。
まず、あなたは極端なケースを分析することができます。
1.k = 2:2つの部屋の需要への最短経路問題
2.k = N:最小スパニングツリーに問題
だから、2を組み合わせて考慮されるべきです。
まず、すべてのキーポイントの最短は、距離dのキーポイントのそれぞれの最も近い点に到達マルチソースを見つけ、あなたは見つけるでしょう:
1.電力が少ないDより大きい場合、その後、点が(他のキーポイントに行ったことがない)破壊する点に来ると仮定すると、
2それぞれの到着を破壊することなく、電池容量がCであると仮定し電源は必ずCDとなる点(この値よりも小さいが、あなたは完全に戻って再び充電され、最も近いキーポイントに行くことができるならば、提供されるものではないの容量以下dより)
したがって、各エッジ(U、V、W)のために、このエッジ条件CDの点V [U]は-w> = D [V]、すなわち、D [U]は+ D [Vを介して点Uに来ることができます] + <W = C、UおよびVの性質は対称です。(この結論は、開始点と終了点が何をキーポイント、またはないでなければならないことを前提に設立されました)
右側は、クラスカルのアルゴリズムを用いて(ランク、圧縮なし経路によって合成)スパニングツリーグローバル最小値を求め、(U、V、D [U] + D [V] + w)の各エッジに変更することができ、その後であってもよいです$ O(LOGN)$照会。全体的に複雑$ O(mlogm + qlogn)$
(Psは:最小再び断面をスパニングツリー場合、この複雑さは、それが$であろうO(mlogm + qloglogn)$、または乗算はRMQ $ Oを行うことができる(mlogm + nloglogn + Q)$)
1の#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 typedefの長い 長いLL。 4 CONST INT N = 3E5 + 10、MOD = 1E9 + 7 。 5 LL INF = 0x3f3f3f3f3f3f3f3f 。 6 INT N、M、K、Q、FA [N]、HD [N]、NE、MXD [N]。 7 のLL D [N]、ヴァル[N]。 8 構造体 E { int型 V、C、NXT;} E [N << 1 ]。 9 構造体E2 { 10 INT U、V。 11 LL C。 12 BOOL 演算子 <(CONST E2&B)のconst { 戻り C < BC;} 13 } E2 [N]。 14 ボイドリンク(INT U、INT V、INT C){E [NE] = {V、C、HD [U]}、HD [U] = NE ++ ;} 15 構造体D { 16 INT U。 17 LL G。 18 ブール 演算子 <(CONST D&B)のconst { リターン G> BG;} 19 }。 20 ボイドをDij(){ 21 PRIORITY_QUEUE <D>Q; 22 のmemset(D、INF、はsizeof D)。 23 のために(INT iは= 1 ; I <= kが; ++ I)q.push({I、D [I] = 0 })。 24 一方(q.size()){ 25 INT U = q.top()U。 26 LL G = 。q.top()G。 27 q.pop()。 28 であれば(dは[U] = G!)続けます。 29 のために(INT ;〜I iは= [U] I = HD {E [I] .nxt) 30 のint V = E [I] .V、C = E [i]は.Cと、 31 であれば(D [V]> D [U] + C)D [V] = D [U] +C、q.push({V、D [V]})。 32 } 33 } 34 } 35 INT FD(INT X){ 戻り FA [X]?FD(FA [X]):X;} 36 空隙 MG(int型のx、int型Y、LL C){ 37 INT FX = FD(X)、FY = FD(Y)。 38 であれば(FX ==年度)のリターン; 39 であれば(MXD [FX]> MXD [FY])スワップ(FX、FY)。 40 FA [FX] = FY、ヴァル[FX] = C、MXD [FY] = MAX(MXD [FY]、MXD [FX] + 1 )。 41 } 42 空隙クラスカル(){ 43 ソート(E2、E2 + M)。 44 のために(INT iは= 1 ; iが<= N; ++ I)MXD [I] = 1、FA [I] = 0 ; 45 のために(INTは iは= 0 ; I <M; ++ I){ 46 INT U = E2 [i]は.U、V = E2 [I] .V。 47 LL C = E2 [i]の.C。 48 MG(U、V、C)。 49 } 50 } 51のLL QRY(INT U、INT V){ 52 LL RET = 0 。 53 用(; U = V;!U =FA [U]){ 54 であれば(MXD [U]> MXD [V])スワップ(U、V)。 55 RET = MAX(RET、ヴァル[U])。 56 } 57 リターンRET。 58 } 59 INT メイン(){ 60 のmemset(HD、 - 1、はsizeof HD)、NE = 0 。 61 のscanf(" %D%D%D%D "、&N、&M、&K&Q)。 62 のために(INT iは= 0 ; I <M ++ {i)が 63 INT U、V、C。 64 のscanf("%D%D%D "、&U&V、&C) 65 リンク(U、V、C); 66 リンク(V、U、C); 67 E2 [I] = {U、V、C}。 68 } 69 をDij(); 70 用(INT iは= 0 ; I <M; ++ I)E2 [i]は.C + = D [E2 [i]は.U] + D [E2 [I] .V]。 71 クラスカル(); 72 ながら(Q-- ){ 73 INT U、V; 74 のscanf(" %D%D "、&U&V); 75 のprintf(" %のLLD \ n "、QRY(U、V)) 。 76 } 77 リターン 0 。 78 }