loj2425「NOIP2015」輸送計画[二分答えツリー差+]

列挙鎖長が$ \ {テキスト半ば} $を超え、その後、テストしようとしない、明らかに二分答え、最長経路を最小限にするために問題の意味を参照してください。`` `` `

リア側は$ \のすべての鎖長ル\テキスト{半ば}、0に設定されているがあるかどうかを確認してください $、 0の鎖長を見つけることによって、その究極の目標すべて$>をさせることですが、\テキスト{中旬} $全体共通の側減算部と、$ \ル\テキスト{中間}となります $ 。

次に、この$ TOTの$の記事の統計はチェーン$ aのパス上に覆い$ \テキスト{半ば}エッジを超え、aはエッジの$ TOTの$時間は条件を有していてもよく覆われているので、貪欲見つける最大の満足条件エッジ、$ \ル\テキスト{中間} $、$ O(N)$差分ツリー缶にすべてのチェーン(すなわち最長鎖)かどうかを確認します。

従って$ O(N \テキスト{ログ} LEN)$。

1の#include <iostreamの>
 2の#include <cstdioを>
 3の#include <CStringの>
 4の#include <アルゴリズム>
 5の#include <cmath>
 6  の#define DBG(X)CERR << #X << "=" << X <<てendl
 7  使って 名前空間はstdを、
8 typedefの長い 長いLL。
9 typedefをダブルデシベル。
10のtypedef対< INTINT > PII。
11テンプレート<型名T>インラインT _min(TA、TB){ 戻り A <Bを?:B;}
 12テンプレート<型名T>インラインT _max(TA、TB){ 戻り A> B?:B;}
 13テンプレート<型名T>インラインチャー MIN(T&A、TB){ 戻り A> B(A = B、?1):0 ;}
 14テンプレート<型名T>インラインチャー MAX(T&A、TB) { 戻り <Bを(A = B、?1):0 ;}
 15テンプレート<型名T>インラインボイド _swap(T&A、T&B){A ^ = B ^ = A ^ = B;}
 16テンプレート<型名T>インラインTリード(T&X){
 17      、X = 0int型の F = 0 ;char型の C; しばらく(isdigit(C = getchar関数())!)の場合(C == ' - ')は、f = 1 ;
18      一方(isdigit(c)参照)、X = X * 10 +(C&15)、C = GETCHAR()。返す fはX = - ?X:X;
19  }
 20  のconst  int型 N = 3E5 + 7 21  構造体 thxorz { INT Wに、NXT;} G [N << 1 ]。
22  構造体 stothx { INTに、NXT、ID;} Q [N << 1 ]。
23  構造体のクエリ{ int型X、Y、LCA、DIS;} Q [N]。
24  int型ヘッド[N]、TOT = 1 、QH [N]、QT。
25  整数N、M、L、R、maxdis、MAXE。
26インラインボイド Addedge(int型のx、int型の Y、int型Z){
 27      G [++ TOT] .TO = Y、G [TOT] .nxt =ヘッド[X]、ヘッドが[X] TOT、G [TOTを] = .W = Z。
28      G [++ TOT] .TO = X、G [TOT] .nxt =ヘッド[Y]、ヘッド[Y] = TOT、G [TOT] .W = Z。
29  }
 30インラインボイド AddQuery(int型のx、int型の Y、int型のID){
 31      Q [++ QT] .TO = Y、Q [QT] .nxt =のQH [X]、QH [X] = QT、Q [ QT] .ID =ID;
32      Q [++ QT] .TO = X、Q [QT] .nxt = QH [Y]、QH [Y] = QT、Q [QT] .ID = ID。
33  }
 34  の#define Y G [j]は.TO
 35  の#define QYのQ [J]は.TO
 36  INT VIS [N]、ANC [N]、DEP [N]を。
37  INT get_anc(INT X){ 戻り X == ANC [x]はx:ANC [X] = get_anc(ANC [X]);}
 38  空隙 tarjan(int型のx、int型FA){
 39      ANC [X] = バツ;
40      のために(登録INT J =ヘッド[X]; J; J = G [J] .nxt)であれば(Y ^ FA)DEP [Y] = DEP [X] + G [J] .W、tarjan(Y、 x)は、ANC [Y] =バツ;
41      VIS [X] = 1 42      のために(登録INT ; J J = Q [J] .nxt J = QH [X])であれば(VIS [QY])
 43          Q [Q [J] .ID] .lca = get_anc(QY)、Q [ Q [J] .ID] .DISの=のDEP [X] + DEP [QY] - (DEP [Q [Q [J] .ID] .lca] << 1 )、MAX(R、Q [Q [J] .ID] .DIS)。
44  }
 45  のint D [N]、デル、CNT。
46  INT DFS(int型のx、int型C){
 47      INT RET = D [X]。
48      のために(登録INT J =ヘッド[X]; J; J = G [J] .nxt)であれば(Y ^ G [C ^ 1 ] .TO)RET + =DFS(Y、J);
49      であれば(RET == CNT)MAX(デル、G [C] .W)。
50      リターンRET;
51  }
 52  の#undef Y
 53  の#undef QY
 54インラインint型チェック(INT MID){
 55      のmemset(D、0はsizeofの D)、デル= CNT = 0 56      のために(登録INT i = 1 ; I <= M; ++ I)の場合(Q [i]は.DIS> MID)++ D [Q [i]は.X] ++ D [Q [I]。 Y]、D [Q [i]は.lca] - = 2、++ CNT。
57の      DFS(10 )。
58      リターン maxdis-デル<= ミッド;
59  }
 60  INTメイン(){ // freopenは( "test.in"、 "R"、STDIN); freopenは( "test.ans"、 "W"、STDOUT)。
61      リード(N)、(m)を読み出します。
62      のために(登録をint i = 1 ; iがn <;、X、Y、Z ++ I)(Z)、読み取り(X)、(y)を読み取る読み取り、Addedge(X、Y、Z)、MAX(L 、Z)。
63      のために(登録をint i = 1 ++; I <= M 読み出す(Q [i]は.X)、読み取り(qは[i]が.Y)、AddQuery(Q [i]が.X、Q [I i)が] .Y、I)。
64      tarjan(10); maxdis = R、MAXE = L; L = RL。//DBG(maxdis)、DBG(MAXE)。
65      一方(L < R){
 66          INTミッド= L + R >> 1 67          もし(チェック(MID))R = ミッド;
68          他の L =ミッド+ 1 ;
69      }
 70      のprintf(" %d個の\ n " 、L)。
71      リターン 0 72 }
コードの表示

要約反射:チェックのボトルネック。キーは、全く見ていないすべてのmaxdisに行うことです。サイドは木の上に行くことをお勧めしますいくつかの統計的な差をカバーして求めています。

おすすめ

転載: www.cnblogs.com/saigyouji-yuyuko/p/11587424.html