トピックへのリンク:https://nanti.jisuanke.com/t/41392
効果の対象:ルートから、父ノードから開始し、木の深さを見つけ、その確率は、それぞれの子に達する正しい深さの確率が得られる依頼します。
問題解決のアイデア:uはサブツリーで示されるDP [U]を書く質問は、Uから正しい答えを得る確率を、アルゴリズムの実行を表面化し始めました。Uは、[U] = 1最深DPを残し、他のDP [U] = 0を残します。転送すると、確率はでき考慮していません。
DP [U] = 1-(1-(Σdp[V])/ CNT [U])^ CNT [U]。[CNT]ノード番号のU U子ノード。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 CONST LL MOD = 1E9 + 7 。 const int型 MAXN = 1E6 + 5 。 構造体ST { int型、次へ。 } STM [MAXN * 2 ]。 int型のTOT; int型のヘッド[MAXN]。 ボイド追加(INT U、INT V){ STM [TOT] .TO = V。 STM [TOT] .next = 頭部[U]。 ヘッド[U]は ++ TOTを= 。 } LL qpow(LL N、LLのM){ LL ANS = 1 。 一方、(M){ 場合(M 1)ANS = ANS * N%MOD。 M / = 2 。 N = N * N%のMOD。 } 戻りANS。 } INT DEP [MAXN]。 int型のmaxdep。 int型DP [MAXN]。 int型のCNT [MAXN]。 ボイド DFS1(int型 U、int型のFA){ DEP [U] = DEP [FA] + 1 。 maxdep = MAX(maxdep、DEP [U])。 にとって(int型 ;〜I I = I =ヘッド[U] {STM [I] .next) INT =までSTM [I] .TO。 もし(FAを==に)続けます。 CNT [U] ++ ; (U、へ)DFS1。 } を返します。 } ボイド DFS2(INT U、INT FA){ LLのTEM = 0 。 以下のために(int型 ;〜I I = I =ヘッド[U] {STM [I] .next) INT =までSTM [I] .TO。 もし(FAを==に)続けます。 (U、へ)DFS2。 TEMの + =DP [します]。 } であれば(DP [U] == 0 ){ TEM = TEM * qpow(CNT [U]、mod- 2)%のMOD。 TEM =(1 -tem + MOD)%MOD。 DP [U] =(1 -qpow(TEM、CNT [U])+ MOD)%MOD。 } } int型のmain(){ int型N; int型のuを、V。 memsetの(頭、 - 1、はsizeof (ヘッド))。 TOT = 0 ; scanf関数(" %のD "、&N) 以下のための(のint i = 1 ; iは++; iがN < {) のscanf(" %d個の%のD "、&U、およびV)。 (V、U)を追加します。 (V、U)を追加。 } DFS1(1、0 ); 以下のために(int型 i = 1 ; iは= N <; iは++ ){ 場合(DEP [I] == maxdep){ DP [I] = 1 。 } 他{ DP [I] = 0 ; } } DFS2(1、0); // coutの<< maxdep <<てendl; // (I = 1 int型私は++; iが<= n)のため のprintf(" %のLLDを\ n "、DP [ 1 ])。 リターン 0 ; }