hdoj4812 Dツリー(点線ルール)

トピックリンクします。https://vjudge.net/problem/HDU-4812

問題の意味:点、最小出力辞書の複数のセットが存在する場合は、ツリーの少し右に与えられ、ポイントを見つけるには、製品のモジュロKの値に等しい重量の経路上に存在します。

アイデア:

  点線ルールテンプレートのタイトル。ID [j]が記録されたと、ルーチンによれば、金型はDISの値をとる後の製品の重心値の中心に右サブツリーのノードを取得するために、重心を見つけるために[I](重心の重量を含め、またそれを含まなくてもよいです)経路の端部は、第2仕切文言の点を使用します。バレルマイン[i]が最小の番号iの重量を記録体積の重心と、再帰。DIS [J]を探しているときに、要件TMPを満たしている:TMP * DIS [J]%MOD = K * V [U]、重み値が重力の質量中心における我々のDISの重心が乗算される含むため二回。次いで逆元、TMP = K * V [U]%MOD *のINV [DIS [J]%MODを使用します。更新バレルの後に完全な答えを更新します。

  ポイントを取得する権利を有する対象を見ていないので(a、b)は、<Bである、と私は(a)は、コンピュータQAQをハンマーしたい、クラッシュをバグを見つけるために、その後、2時間を満たしていることと思います....

ACコード:

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

インラインint型リード(){
     int型のx = 0、F = 0CHAR CH = 0 一方、(isdigit(CH)!){| F = CH == ' - ' ; CH = GETCHAR();}
     ながら(isdigit(CH))x =(x << 3)+(X << 1)+( CH ^ 48)、CH = GETCHAR()。
    リターン?F - X:X; 
} 

のtypedef長い 長いLL。
const  int型 MAXN = 1E5 + 5 const  int型 MOD = 1E6 + 3 ;
const  int型 MAXK = 1E6 + 5 const  int型 INF = 0x3f3f3f3f 構造体ノード1 {
     int型V、NEX。
}エッジ[MAXN << 1 ]。

構造体NODE2 {
     int型X、Y。
    NODE2(){X = Y = 0 ;} 
    NODE2(int型のx、int型のY):X(X)、Y(Y){} 
} ANS。

ブール 演算子< (NODE2、NODE2 b)は{
     場合(AX == BX)戻り AY < によって、
    リターン斧< BX。
} 

int型N、K、CNT、ヘッド[MAXN]、SZ [MAXN]、MSON [MAXN]、最小、根、サイズ。
INT VIS [MAXN]、鉱山[MAXK]、ID [MAXN]、T、TT。
LL V [MAXN]、DIS [MAXN]、INV [MAXK]。

無効(){INITを
    INV [ 1 ] = 1 以下のためにint型 I = 2、I <MAXK; ++ I)
        INVの[I] =(MOD-MOD / I)* INV [MOD%I]%MOD。
} 

ボイド ADDE(INT U、INT  V){
    エッジ[++ CNT] .V = V。
    エッジ[CNT] .nex = 頭部[U]。
    ヘッド[U] = CNT。
} 

ボイド getroot(int型 U、int型のFA){ 
    SZ [U] = 1、MSON [U] = 0 ;
    以下のためにint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V = エッジ[I] .V。
        もし(VIS [V] || V == FA)続けます
        getroot(V、U); 
        SZ [U] + = SZ [V]。
        MSON [U] = MAX(MSON [U]、SZ [V])。
    }
    MSON [U] = MAX(MSON [U]、サイズSZ [U])。
    もし(MSON [U] <分)分= MSON [U]、ルート= U。
} 

ボイド getdis(INT U、INT FA、LL LEN){ 
    DIS [ ++ T] = LEN、ID [T] = U。
    以下のためにint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V = エッジ[I] .V。
        もし(VIS [V] || V == FA)続けます
        getdis(V、U、lenの * V [V]%MOD)。
    } 
} 

ボイド(解決INT U){ 
    鉱山[Vを[U] = U、T = 0 にとってint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V = エッジ[I] .V。
        もし(VIS [V])続けます
        TT = T; 
        getdis(V、U、V [U] * V [V]%MOD)。
        INT J = TT + 1、J <= T; ++ J){     
            LL TMP = 1LL * K * V [U]%MOD *のINV [DIS [J]%MOD。
            もし(鉱山[TMP] == INF)を続けます
            他のノード2; 
            もし(鉱山[TMP] <ID [J])other.x =鉱山[TMP]、other.y = ID [J]。
            other.x = ID [j]を、other.y = 鉱山[TMP]。
            もし(他の<ANS)ANS = その他; 
        } 
        のためのINT J = TT + 1、J <= T; ++ j)は
            鉱山[DIS [J] = 分(鉱山[DIS [J]、ID [J])。
    } 
    鉱山[V [U] = INF。
    以下のためにint型 I = 1 ; I <= T; ++ I)
        鉱山[DIS [I] = INF。
} 

ボイド fenzhi(INT U、INT ssize){ 
    VIS [U] = 1 
    (U)を解きます。
    にとってint型 ; I I = I =ヘッド[U] {エッジ[I] .nex)
         のint V = エッジ[I] .V。
        もし(VIS [V])続けます = INF、ルート= 0 
        サイズ = SZ [V] <SZ [U] SZ [V] :( ssize-?SZ [U])。
        getroot(V、0 ); 
        fenzhi(根、サイズ)
    } 
} 

int型のmain(){ 
    INIT()。
    memset(鉱山、0x3fをはsizeof (鉱山))。
    一方、(〜のscanf(" %D%dの"、&​​N&K)){ 
        CNT =0 ; 
        ans.x = ans.y = N + 1 以下のためにint型 i = 0 ; iは= N <; ++ I)
            ヘッド[I] = VIS [I] = 0 ;
        以下のためにint型 i = 1 ; iは= N <; ++ I){
             int型 TMP =は(読み取り)。
            V [i]は = TMPと、
        } 
        のためにint型 i = 1 ; iがn <; ++ I){
             int型、U =(読み取り)、V = 読み取ります(); 
            ADDE(U、V); 
            ADDE(V、U);
        } = INF、ルート= 0、サイズ= N。
        getroot(10 ); 
        fenzhi(根、N)。
        もし(ans.x == N + 1 
            のprintf(" いいえ溶液を\ n " );
        
            のprintf(" %D%D \ N " 、ans.x、ans.y)。
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/FrankChen831X/p/11391489.html