3669 bzoj

基本的な考え方bzoj 2594ステップよりも、より多くの

私たちが最初に見つかったものは、財産の二つの側面があるということでしたので、我々は最初の人制限を削除検討します

我々は、すべての小から大への$ $の降順によって側面、その後、最小スパニングツリーのメンテナンスに追加

プラス側の$ B $は操作bzoj 2594のサイズに合わせてあるたびに、その答えを更新することができます

あなたはまだユニコム出力がない場合は-1

書式#include <cstdioを> 
する#include <cmath> 
の#include <CStringの> 
の#include <cstdlib> 
書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <キュー> 
の#include <スタック> 
の#include <マップ>
 使用して 名前空間はstd;
構造体QUES 
{ 
    int型X、Y、TYP、NUM。
} Q [ 1000005 ]。
構造体のエッジ
{ 
    int型のL、R、V1、V2。
    フレンドブール 演算子 < (エッジA、エッジB)
    { 
        リターン?a.v1 == b.v1 a.v2 <b.v2:a.v1 < b.v1。
    } 
}エッジ[ 1000005 ]。
マップ <ペア< int型int型 >、int型 > M;
INTのN、M、Q。
INT CH [ 2000005 ] [ 2 ]。
int型 VIS [ 2000005 ]。
int型 MAXX [ 2000005 ]。
int型のval [ 2000005 ]。
INT [F 2000005 ]。
int型 FL [ 2000005 ]。
int型のRET [ 2000005 ]。
空隙アップデート(INT X)
{ 
    MAXX [X] = valの[X]。
    もし(エッジ[MAXX [CH [X] [ 0 ]]] V2>エッジ[MAXX [X]] V2。)MAXX [X] = MAXX [CH [X] [ 0 ]]。
    もし(エッジ[MAXX [CH [X] [ 1 ]]] V2>エッジ[MAXX [X]] V2。)MAXX [X] = MAXX [CH [X] [ 1 ]。
} 
ブール be_root(INT X)
{ 
    場合(CH [F [X]] [ 0 ] == X || CH [F [X]] [ 1 ] == x)をリターン 0 リターン 1 ; 
} 
ボイドプッシュダウン(int型X)
{ 
    もし(FL [X])
    { 
        スワップ(CH [CH [X] [ 0 ] [ 0 ]、CH [CH [X] [ 0 ] [ 1 ])。
        スワップ(CH [CH [X] [ 1 ] [ 0 ]、CH [CH [X] [ 1 ] [ 1 ])。
        FL [CH [X] [ 0 ]] ^ = 1、FL [CH [X] [ 1 ] ^ = 1 ; 
        FL [X] = 0 ; 
    } 
} 
ボイド repush(INT X)
{ 
    場合(!repush(F [X])be_root(X)); 
    プッシュダウン(X)。
} 
のボイド回転(int型X)
{ 
   int型、Y = F [X]、Z = F [Y]、K =(CH [Y] [ 1 ] == X)
    もし(!be_root(Y))CH [Z] [CH [Z] [ 1 ] == Y] =のX。
    F [X] = Z; 
    CH [y]は[K] = CHを[X] [K!]、F [CH [X] [] kは!] = yと; 
    CH [X] [ = Y、F [Y] = kを!] X。
    アップデート(Y)、更新(X)。
} 
ボイドスプレイ(INT X)
{ 
    repush(X)。
    一方、(be_root(X)&&!X)
    { 
        int型、Y = F [X]、Z = F [Y]。
        もし(!be_root(Y)&& y)は
        {
            もし((CH [Y] [ 1 ] == X)^(CH [Z] [ 1 ] == Y))に回転(X)
            そうでなければ(Y)を回転させます。
        } 
        回転(X)
    } 
    更新(X)
} 
ボイドアクセス(INT X)
{ 
    int型、Y = 0 一方、(X)
    { 
        スプレイ(X)。
        CH [X] [ 1 ] = yと、
        更新(X)。
        Y = X、X = F [X]。
    } 
} 
ボイド makeroot(INT X)
{  
    アクセス(X)、スプレイ(X)。
    スワップ(CH [X] [ 0 ]、CH [X] [ 1 ])、FL [X] ^ = 1 ; 
} 
ボイドリンク(int型のx、int型のY)
{ 
    makeroot(X)。
    F [X] = yと、
} 
ボイドスプリット(int型のx、int型のY)
{ 
    makeroot(X)、アクセス(Y)、スプレイ(Y)。
} 
ボイドカット(int型のx、int型のY)
{ 
    スプリット(x、y)を、CH [Y] [ 0 ] = F [X] = 0 、更新(Y)。
} 
INT findf(INT X)
{
    アクセス(X)、スプレイ(x)が、プッシュダウン(X)。
    一方、(CH [X] [ 0 ])、X = CH [X] [ 0 ]、プッシュダウン(X)。
    リターンのx; 
} 
インラインint型リード()
{ 
    int型、F = 1、X = 0チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1 ; CH = GETCHAR();}
     一方(CH> = ' 0 ' && CH <= ' 9 '){X = X *10 + CH- ' 0 ' ; CH = GETCHAR();}
     戻りのx *のF。
} 
int型のmain()
{ 
    N =(読み取り)、M = read()は、
    int型 iは= 1 ; I <= M; iが++ 
    { 
        エッジ[I] .L =(読み取り)、エッジ[I] .Rは、read()は、エッジ= [I] .v1 =(読み取り)、エッジ[ i]を.V2 = 読み取ります();
        もし(エッジ[I] .L> エッジ[I] .R)スワップ(エッジ[I] .L、エッジ[I] .R)。
    } 
    ソート(エッジ + 1、エッジ+ M + 1 )。
    int型 ANS = 0x3f3f3f3f 以下のためにint型 i = 1 ; iが<= M; iは++)valが[iが+ N] = MAXX [iが+ N] = I。
    以下のためにint型 I = 1 ; I <= M iは++ 
    { 
        int型 F1 = findf(エッジ[I] .L)、F2 = findfを(エッジ[I] .R)。
        もし(F1 == F2)
        { 
            スプリット(エッジ[I] .L、エッジ[I] .R)。
            もし(エッジ[MAXX [エッジ[I] .R] V2> エッジ[I] .V2)
            { 
                int型 T = MAXX [エッジ[I] .R]。
                カット(エッジ[T] .L、T + N)、カット(エッジ[T] .R、T + N)。
                リンク(エッジ[I] .L、私 N +)、リンク(エッジ[I] .Rは、iが+ n)を。
            } 
        } 他のリンク(エッジ[I] .Lは、iがN +)、リンク(エッジを[I] .R iは+ N)。
        INT FF1 = findf(1)、FF2 = findf(N)。
        もし(FF1 == FF2)
        { 
            スプリット(1 、N)
            ANS =分(ANS、エッジ[i]を.v1 + 。エッジ[MAXX [N] V2)。
        } 
    } 
    もし(ANS == 0x3f3f3f3f)のprintf(" -1の\ n " );
    のprintf(" %d個の\ nを" 、ANS)。
    リターン 0 
}

 

おすすめ

転載: www.cnblogs.com/zhangleo/p/11164659.html