トピックリンクします。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 = 0。CHAR 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(1、0 ); fenzhi(根、N)。 もし(ans.x == N + 1 ) のprintf(" いいえ溶液を\ n " ); 他 のprintf(" %D%D \ N " 、ans.x、ans.y)。 } 戻り 0 。 }