羅区P2173 / BZOJ2816 [ZJOI2012]ネットワーク

もし$ C = 0 $(すなわち、一つだけの色)をLCT aを開き、ノードの次数を維持するために、だから今$ C <10 $、一緒に維持して、$ LCTツリーを$のC + 1を開く考えます。それを見つけるためにマップ上に直接サイド。

書式#include <cstdioを> 
する#include <マップ>
 使用して 名前空間はstdを、
const  int型の N = 10005 ;
チャーはrB [ 1 << 21 ]、* rSを、* をrT。
インラインチャー GC(){ 戻り rSを==をrT &&(RT =(RS = rBの)+関数fread(RB、11 << 21、STDIN)はRS == RT)EOF:* rSを++ ;} 
インラインint型RD( ){
     チャー C = GC()。
    一方、(C < 48 || C> 57)C = GC()。
    int型のx = C&15;
    (C = GC(); C> = 48個の && C <= 57、C = GC())x =(x << 3)+(X << 1)+(C&15 )。
    リターンのx; 
} 
INT ヴァル[N]、ST [N]、SL。
構造体の縁{
     int型Uを、V。
    エッジ(){} 
    エッジ(int型のx、int型のY){
         場合(X <Y){U = X; V = Yであり;}
          {UはYを=; V =のX;} 
    } 
    インラインブール 演算子 <(constのエッジ&B )CONST { リターンU <BU || U == BU && V < BV;} 
}。
地図 <エッジ、INT > F。
構造体LCT {
     INT MAXN [N]、F [N]、CH [N] [ 2 ]、D [N]を。
    BOOL タグ[N]。
    インラインブール NRT(INT O){ 戻り [[[O] F] CH 0 [[[O] F]] == O || CH 1 ] == O;} 
    インラインブール DIR(INT O){ 戻り CH [ F [O]] [ 1 ] == O;} 
    インラインボイドフリップ(INT O){
         もし(O){
             int型 T = CH [O] [ 0 ]; CH [O] [ 0 ] = CHを[O] [ 1 ]; CH [O] [ 1 ] = T。
            タグ[O] ^ = 1 ; 
        } 
    } 
    インラインボイド押し上げ(INT O){ 
        MAXN [O] = MAXN [CH [O] [ 0 ]]> MAXN [CH [O] [ 1 ] MAXN [CH [O] [?0 ]:MAXN [ CH [O] [ 1 ]。
        もし(ヴァル[O]> MAXN [O])MAXN [O] = valの[O]。
    } 
    インラインボイド PUSHD(INT O){
         もし{([の]バナー)
            フリップ(CH [の] 0 ]);フリップ(CH [A] [ 1 ])。
            バナー[T] = 0 ; 
        } 
    } 
    インラインボイド腐朽(int型D){
         int型 4 = F [t]を。
        ブール D = DIR(D)。
        V [T] = F [4]。
        強制(NRT(4))CH [F [第4] [DIR(4つ)= 強制(CH [4] [D]をCH = [A]、[D ^ 1 ])V [CH [4] [D] = ; 4 
        V [CH [A]、[D ^ 1 ] = 4個] = 
        突き上げ(4つ)。
    }
    インラインボイドスプレイ(INT O){
         int型 K = ST [SL = 0 ]は、= Oと、
        一方、(NRT(K)){K = F [k]は、ST [++ SL] = K;}
         ながら(SLは> = 0)PUSHD(ST [sl-- ])。
        (腐敗(O); NRT(O))であれば((DIR(O)^ DIR([O] F))?(NRT(F [O]))腐敗:[O] F O)
        突き上げ(O)
    } 
    インラインボイドアクセス(INT X){
         ためint型、Y = 0 ; X; X = F [Y = X]){ 
            スプレイ(X)。
            CH [X] [ 1] = Y。
            突き上げ(X)。
        } 
    } 
    インラインINT findrt(INT X){ 
        アクセス(X)、スプレイ(X)。
        ため(PUSHD(x)は、をch [X] [ 0 ]; PUSHD(X))×= CHを[X] [ 0 ]。
        スプレイ(X)。
        リターンのx; 
    } 
    インラインボイド makert(INT X){ 
        アクセス(X)、スプレイ(X)。
        フリップ(X)。
    } 
    インラインボイドリンク(int型のx、int型のY){ 
        makert(X)。
        ++ D [X]; ++ D [Y]。
        F [X]= Y。
    } 
    インラインボイドカット(int型のx、int型のY){ 
        makert(x)は、アクセス(Y)、スプレイ(X)。
        [X] --d; - D [Y]を。
        CH [X] [ 1 ] = F [Y] = 0 
        突き上げ(X)。
    } 
} LCT [ 10 ]。
INT {main()の
     整数 N = RD()、M = RD()、C = RD()、Q = RD()、I、J、U、V、W、P、選びます。
    (i = 1 ; iは= N <; ++ I){ 
        ヴァル[I] = RD()。
        (J = 0 ; J <C; ++ j)はLCT [J] .maxn [I] = valの[I]。
    }
    一方、(M-- ){ 
        U = RD(); V = RD(); W = RD()。
        LCT [W] .link(U、V)。
        F [エッジ(U、V)] = W。
    } 
    一方(q-- ){ 
        OPT = RD(); U = RD(); V = RD()。
        もし(!OPT){ 
            valの[U] = V;
            (i = 0 ; iはCを<; ++ I)LCT [I] .splay(U)。
        } そう であれば(OPTの== 1 ){ 
            W = RD()。
            もし(f.find(エッジ(U、V))== f.end()){プット("そのようなエッジありません。"); 続ける ;}   // 用或者カウント、不要用[]見つける 
            P = F [エッジ(U、V)];
             場合(==のP W){プット(" 。成功"); 続ける;}
             もし( .D [U]> = [W] LCT 2 || LCT .D [W] [V]> = 2){プット(" エラー1. " ;)継続;} 
            LCT [W] .makert(U)。
            もし(LCT [W] .findrt(V)== U){プット(" エラー2 "); 続ける;} 
            プット(" 成功。"); 
            LCT [P] .cut(U、V); LCT [W] .link(U、V)。
            F [エッジ(U、V)] = W。
        } そう であれば(OPTの== 2 ){ 
            LCT [U] .makert(V)。
            もし(!LCT [U] .findrt(ワット= RD())= v)のプット(" -1 " );
            のprintf(" %d個の\ n " 、LCT [U] .maxn [V])。
        } 
    } 
    戻り 0 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/sunshine-chen/p/11294548.html