Luogu1967 noip2013 [] []トラック輸送[スパニングツリークラスカルLCA]

P1967の運送
最大ツリー経路+最小乗算演算子にまたがります

一般クラスカルのように下降するエッジをクラスカルときスパニングツリーは最大であります

LCAは、言った、他のサン・オペレーションのテンプレートと乗算されたよう

また、前処理パス重み最小値または最大値と権利情報などの時、このように記録することができる、得られるように右ツリーOの2点間の経路(LOGN)時間最大値、最小値と題されています

書式#include <iostreamの> 
の#include <cstdioを> 
する#include <キュー> 
の#include <CStringの> 
の#include <cmath> 
の#include <スタック> 
の#include <アルゴリズム>
 使用して 名前空間はstdを、
#defineっ長い長
 の#define RGレジスタ
 のconst  int型 N = 100000 + 5、M = 500000 + 5、INF = 0x3f3f3f3f、P = 19650827 INTのN、M、Q。
INT DEP [N]、P [N] [ 25 ]、[N] W [ 25 ]。
テンプレート < クラス T> ボイド RD(T&X){ 
    X = 0INT W = 0CHAR CH = 0 しばらく W | = CH ==(isdigit(CH)!)' - '、CH = getchar関数();
    一方、(isdigit(CH))X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR()。
    X?= W - X:X; 
} 

int型のヘッド[N]、TOT = 0 、ANS。
構造体のエッジ{ int型V、NXT、W;} E [M]。
空隙追加(int型 U、int型 V、INT W){ 
    E [ ++ TOT =(エッジ){V、ヘッド[U]は、W};頭部[U]は= TOT。
} 

INT F [N]。
構造体ノード{
     int型U、V、W。
} ND [M]。
ブール CMP(ノードA、ノードB)は、{ 戻る AW> BW;}
 int型の検索を(INT X){ リターン:F [X] = [X] == X X F 、検索(F [X])}
 ボイドクラスカル(){
     int型の CNT = 0 以下のために(RGのINT i = 1 ; iが<= N; ++ I)F [I] = I。
    (RG用のint i = 1 ; I <= M ++、U、V、W {I)
        U = ND [i]は.U、V = ND [I] .V、W = ND [i]は.W ;
        場合(見つける(U)=!見つける(V)){ 
            F [F [U] = F [V]。
            ++ CNT; 
            (Uは、V、W)、追加(V、U、W)。
            もし(CNT == N- 1ブレーク
        } 
    } 
} 

ボイド DFS(int型U)を{
     ためint型 V、I =ヘッド[U]; I; I = E [I] .nxt){ 
        V = E [I] .V。
        もし(!DEP [V]){//未走过 
            DEP [V] = DEP [U] + 1 
            P [V] [ 0 ] = U。
            [V]、W [ 0 ] = E [I] .W。
            DFS(V); 
        } 
    } 
} 
ボイドビルド(){
     (RG のint i = 1 ; I <= N; ++ I){
         場合(!{DEP [i])と
            DEP [I] = 1 
            P [I] [ 0 ] = 0 ; 
            DFS(I); 
        } 
    } 
    DFS(1)。//连起来の
    ためint型 i = 1 ; iは<= 20 ; I ++ のためのINT J = 1 ; J <= nであり、j ++ ){ 
            P [j]は[I] = P [P [j]は[I- 1 ] ] [I- 1 ]。
            W [J] [I] =分(W [j]は[I- 1 ]、W [P [j]は[I- 1 ]] [I- 1 ])。
        } 
} 

int型(LCAをINT A、INT B){ 
    ANS = INF。
    もし(DEP [A]> DEP [B])スワップ(B)
    以下のためのint型私は= 20、I> = 0 ; - I){
         場合(DEP [P [B] [I] <DEP [A])続けます
        ANS =分(ANS、W [B] [I]); B = P [B] [I]。
    } 
    もし(== b)は戻りANS。
    以下のためにint型 iは= 20、I> = 0 ; - I){
         場合(P [A] [I] == P [B] [i])と続けます
        ANS = 分(ANS、分([A]、W [i]は、[I])[B] W)。P = [A] [I]、B = P [B] [I]。
    } 
    ANS =分(ANS、分([A] [W 0]、W [B] [ 0 ]));
    戻るANSを。
} 

int型のmain(){
     // freopenは( "in.txt"、 "R"、STDIN)。
    memset(DEP、0はsizeof (DEP))。
    memsetの(p、0はsizeof (P))。
    RD(n)は、RD(M)。
        int型U、V、W;
    (RG int型 I = 1 ; I <= M ++ {I)
        RD(U)、RD(V)、RD(W)。
        ND [I] = (ノード){U、V、W}。
    } 
    ソート(ND + 1、ND + 1 + M、CMP)。
    クラスカル();
    ビルド(); 
    RD(Q)。
    (RG int型 I = 1 ; I <= Q ++ {I)
        RD(U)、RD(V)。
        場合(見つける(U)=(v)を見つける!)のprintf(" -1です\ n " );
        のprintf(" %d個の\ nを" 、LCA(U、V)); 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/lxyyyy/p/10960467.html