[羅区P2387] [NOI2014]魅惑の森

タイトル説明:https://www.luogu.org/problem/P2387

 

分析:2ポイントのUVは、それらの間に小さな値をエッジ、b値も小さい:、その後、明らかに貪欲ではないと思うの最大値は、対象の最低要件である第一に考え二つの点が、2つの変数があります間違いなく良い方。だから値による最初の側面、そしてb値により最小スパニングツリーを維持します。それは手に負えない最小スパニングツリーに出現した場合に新たに挿入された側のために、我々は、元のその端を切断、それがある場合に側端で最大のリングは、これよりも大きいクエリ。最小スパニングツリーにそれを維持するために、どのように何I風雲?明らかにLCT。しかし、我々はその境界を維持したい、それを行う方法?ルーチンはマルチポイントを構築することです、そして右側、最初と最後に割り当てられたポイントの値は、それぞれ、この辺に接続することができます。

 

詳細:1.いいえ詳細は、ハングのように書いていません。

コードを接続します。

#include <cstdioを> 
する#include <iostreamの> 
する#include <アルゴリズム> 
 使用して 名前空間STD; 

// グラフが与えられると、各エッジは、出発点への経路を見つけるために、2 AB&重みを有する
 // ように、このパスを最大値と最大値と最小値Bは上

CONST  INT MAXN = 50005、MAXM = 200005 ;
 INT N-、M、
 構造体のエッジ{
     INT U、V、B; 
}エッジ[MAXM]; 
int型FA [MAXMを];
 構造体ノード{
     int型 MAX、ヴァル、息子[ 2 ;〕、FA
     BOOLのflag_reverse; 
}ノード[MAXMを << 1 ];
 INTANS = 0x3f3f3f INT STK [MAXM << 1 ]。

インラインint型リード(){
     int型 RET = 0、F = 1チャー C = GETCHAR()。
    一方、(C < ' 0 ' || C> ' 9 '){ もし、(C == ' - ')= -f F; C = GETCHAR();}
     一方、(C> = ' 0 ' && C <= ' 9 '){RET = RET * 10 + C- ' 0 '; C = GETCHAR()}
     戻りのRET *のF。
} 

ボイド readIn(INT I){ 
    エッジ[I] .U読み取り=();エッジ[I] .V読み取り=();エッジ[I] .A)(読み取る。=、エッジ[i]は.Bは。= 読み取ります( ); 
    エッジ[I + 1 ] .U =エッジ[I] .U、エッジ[I + 1 ] .V =エッジ[I] .V、エッジ[I + 1 ] .A =エッジ[I] .A、エッジ[I + 1 ] .B = エッジ[I] .B。
} 

INT union_find(INT X){
     場合(X == FA [X])戻りX。
     戻り FA [X] = union_find(FA [X])。
} 

無効アップデート(int型X){ 
    ノード[X] .MAX =のX。
    INTの LSON =ノード[X] .son [ 0 ]、rson =ノード[X] .son [ 1 ]。
    もし(LSON &&ノード[ノード[LSON] .MAX] .val>ノード[ノード[X] .MAX] .val)ノード[X] .MAX = ノード[LSON] .MAX。
    もし(rson &&ノード[ノード[rson] .MAX] .val>ノード[ノード[X] .MAX] .val)ノード[X] .MAX = ノード[rson] .MAX。
} 

ボイドプッシュダウン(int型X){
     場合(ノード[X] .flag_reverse){
         int型 LSON =ノード[X] .son [ 0 ]、rson =ノード[X] .son [ 1 ]。
        ノード[LSON] .flag_reverse ^ = 1つの ;
        ノード[rson] .flag_reverse ^ = 1 ; 
        ノード[X] .flag_reverse ^ = 1 ; 
        スワップ(ノード[X] .son [ 0 ]、ノード[X] .son [ 1 ])。        
    } 
} 

int型 GETint型x)は{
     返す X ==ノード[ノード[X]の.Fa] .son [ 0 ] || X ==ノード[ノード[X]の.Fa] .son [ 1 ]。
} 

int型のチェック(int型X){
     戻り X ==ノード[ノード[X]の.Fa] .son [ 1 ]。
} 

ボイド回転(INT X){
     int型Y =ノード[X]の.Fa、Z =ノード[Y]の.Fa、D =チェック(X)、XX =ノード[X] .son [D ^ 1 ]。
    ノード[Y] .son [D] = XXを、もし(XX)ノード[XX]の.Fa = Y。
    もし取得(Y))ノード[Z] .son [チェック(Y)] = xと、ノード[X]の.Fa = Z。
    ノード[X] .son [D ^ 1 ] = Y;ノード[Y]の.Fa =のX。
    アップデート(Y)、更新(X)。
} 

ボイドスプレイ(INT X){
     int型、Y = Xの、トップ= 0 ; STKの[++トップは] = yと、
    一方、取得(Y))STKの[++トップ] = Y = ノード[Y]の.Fa。
    一方(上部)プッシュダウン(STK [top-- ])。
    同時に取得{(x))を
         int型 Y = ノード[X]の.Fa。
        もし取得(Y))
            回転(チェック(X) ==チェック(Y)?Y:X); 
        (x)は、回転、
    } 
} 

ボイドアクセス(INT X){
     int型 XX = 0 一方、(X){ 
        スプレイ(X)。
        ノード[X] .son [ 1 ] = XXと、
        XX = X。
        更新(X)。
        X = 節点[X]の.Fa。
    } 
} 

int型の検索(INT X){ 
    アクセス(X)、スプレイ(x)は、
    一方(ノード[X] .son [0 ])はx =ノード[X] .son [ 0 ]。
    リターンのx; 
} 

空隙 make_root(INT X){ 
    アクセス(X)、スプレイ(X)。
    ノード[X] .flag_reverse ^ = 1 ; 
} 

ボイドリンク(int型のx、int型のY){ 
    make_root(X)。もし(!)(Yを見つける= X)ノード[X]の.Fa = Y。
} 

ボイドスプリット(int型のx、int型のY){ 
    make_root(x)は、アクセス(Y)、スプレイ(Y)。
} 

ボイドカット(int型のx、int型のY){ 
    スプリット(X、Y)
    もし()(Yを見つける== X &&ノード[X] .son [!1 ] &&ノード[X]の.Fa == y)は
        ノード[X]の.Fa =ノードを[Y] .son [ 0 ] = 0 ; 
} 

int型の照会(int型のx、int型のY){ 
    スプリット(X、Y)
    戻りノード[Y] .MAX。
} 

ボイドワーク(){
     ためint型 I = 1 ; I <= M; ++ i)は、FA [I] = I。
    以下のためにint型 I = 1 ; I <= M iは++ ){
         int型、U =エッジ[I] .U、V = エッジを[I] .V。
        もし(union_find(U)==union_find(V)){
             int型、T = クエリ(U、V)。
            もし(エッジ[I] .B < ノード[T] .val){ 
                カット(T、エッジ[T - N] .U)。
                カット(T、エッジ[T - N] .V)。
            } 
            {
                 場合(union_find(1)== union_find(N))
                    ANS =分(ANS、エッジ[I] .A +ノード[クエリ(1 、N)]のVal);
                続け; 
            } 
        } 
        他の FA [union_find(U)] = union_find(V)。
        ノード[iが+ N] .MAX = iがN +、ノード[iがn] .val = + エッジ[I] .Bと、
        リンク(U、iは N +)、リンク(私を+ N、V)。
        もし(union_find(1)== union_find(N))
            ANS =分(ANS、エッジ[I] .A +ノード[クエリ(1 、N)]のVal); 
    } 
    場合(ANS =!0x3f3f3f 
        のprintf(" %dの" 、ANS)。
     
        のprintf(" -1 " ); 
} 

BOOL CMP(エッジA、エッジB){
     戻り Aaの< Baのを、
} 

INT {main()の
    N= READ(); M =読み取る(); M << = 1 以下のためにint型私= 1 ; I <= M; iが+ = 2 )readIn(I)。
    ソート(エッジ + 1、エッジ+ M + 1 、CMP)。
    作業(); 
    リターン 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/JoshDun/p/11324299.html