質問の意味:
ツリーのn点のエッジの重みは0または1で与えられ、有効なパス(x、y)は(Y≠をx)が満たされ、X yから移動し、一旦エッジの右側を通って、そうではありません次いで0側に右側を通って、条件を満たすエッジの数を見つけますか?
思考:セットの$ F [U] $ 1のルートであり、ボトムエンドノード$ U $は有効パス1の数は、$ G [U]ルートの$ 1代表、ボトムアップであります$のV $エンド・ノードが正当なパス0の数であり、これは再び単純DFSによって解決することができます。
次に、設定$ NF [U] $と$ NG [u]がuはルート・パス、整流DFSルート、プロセスのルート変更である法的$の2種類の数を表します。
一方の側の縁は、その後、0の場合:
$呉[st.to] = NG [U] $、$ NF [st.to] = [st.to] F $。この式はまた、よく理解され、パスの白側が変更されない、パスが不正である場合にエッジ上に上から下に、親ノードから転送されたすべての黒。
図1は、次いで、側縁である場合:
$ン[st.to] = G [st.to] $、$ NF [st.to] = NF [U] -g [st.to] + ngの[U] $は、白エッジは、底部から出てきますの。ブラックにより形成された側縁部と、親ノードプラス白側を接続して形成されたエッジの親ノード黒と白側の現在位置側に黒側を差し引きます。
#pragma GCCの最適化(2) の#pragma G ++最適化(2) の#pragmaコメント(リンカー、 "/ STACK:102400000,102400000") の#include <ビット/ STDC ++ H> の#include <cstdioを> する#include <ベクトル> の#define担当者(iは、、B)のための(iは= int型、iが<= bは、iが++) の#define DEP(I、B、A)(iはBを= int型;方には> =; i--) の#define CLR(B)のmemset(A、B、はsizeof(A)) の#define PB一back の#define PII対<整数、整数> 使用して 名前空間STDを、 typedefの長い 長いLL。 const int型 MAXN = 200010 ; LL用RD() { LL X = 0、F = 1。チャー 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型のT。 構造体の縁{ INT W、であり; }。 ベクター <エッジ> VEの[MAXN]。 INT F [MAXN]、G [MAXN]、NF [MAXN] ngの[MAXN]。 INTのN、M。 ANS LL; ボイド dfs_1(int型 U、int型のFA){ ための(自動&ST:VEの[U]){ 場合(st.to == FA)続けます。 dfs_1(st.to、U)。 もし(st.w == 0 ){ G [U] + = G [st.to] + 1 。 } 他{ [U] F [st.to] + + = F 1 +G [st.to]。 } } } ボイド dfs_2(INT U、INT FA){ ANS + = NF [U] + [U]をngの。 用(オート&ST:VEの[U]){ 場合(st.to == FA)続けます。 もし(st.w == 0 ){ NG [st.to] = NG [U]。 NF [st.to] = [st.to] F。 } 他{ NG [st.to] = G [st.to]。 NF [st.to] = NF [U] -g [st.to] + ngの[U]。 } dfs_2(st.to、U)。 } } int型のmain(){ CIN >> N。 担当者(I、1、N- 1 ){ int型、U、V、W。 scanf関数(" %D%D%D "、およびuは、&V、およびW) VEの[U] .pb({V、W})。 [V] .pb({U、W})まし。 } dfs_1(1、0 ); NF [ 1 ] = F [ 1 ]、NG [ 1 ] = G [ 1 ]。 dfs_2(1、0 ); coutの << ANS << てendl; }