質問の意味: N個のノードのツリーを考えると、1 <= N <= 50000このノードにおける商品価格に代わって、各ノードの重みを持っています。ノードbへの一つのノードからビジネスマン、および商品のみを購入し、販売することができますが、利益のどのくらいを依頼するまで生成することができます。
思考:パス圧縮は、各点が現在のルート情報を取得し、更新することができます。ダブルであり行うことができます。
コードがコピーされるずっと前に。
#include <cstdioを> の#define分(A、B)(<B:B) の#define MAX(a、b)は(A> B A:B) の#defineスワップ(B)(^ = B、B ^ = A、A 2 = B) 使用して 名前空間STDを、 const int型ミリメートル= 333333 ; const int型 MN = 55555 ; INT S [mm]で、T [mm]で、D [mm]と、P [mm]は、[mm]をANS。 INT H [MN] = { 0 }、Q [MN] = { 0 }、G [MN] = { 0 }、F [MN]、MX [MN]、アップMI [MN]、[MN] = { 0 }、DW [MN] = { 0 }。 BOOL VIS [MN] = { 0 }。 int型I、J、K、N、M、E。 列をなしてボイド追加(int型 U、int型 V、int型 C、INT H []) { S [E] = U、T [E] = V、D [E] = cで、P [E] = hの[U]、H [U] = E ++ 。 S [E]は、C、P [E] = H [V]、H [V] = E ++ - V、T [E] = U、D [E]を= = 。 } INT(見つけるINT X) { 場合(F [X] == x)をリターンXと、 INT Y = F [X]。 F [X] = ([X] F)を見つけます。 アップ[X] = MAX(MX [Y] - MI [x]は、MAX()[Y] [x]は、アップまで)。 DW [X] = MAX(MX [X] - MI [Y]、MAX(DW [x]は、DW [Y]))。 MX [X] =MAX(MX [x]は、MX [Y])。 MI [X] = 分(MI [x]は、MI [Y])。 戻り[X] F; } ボイド tarjan(INT U) { int型I、V、X、Y。 VIS [U] F = = U] 1 。 以下のための(I = Q [U]; I; I = P [i])と する場合(VIS [V = T [I]) V =見つける(V)、T [E] = I、P [E] = G [V]、G [V] = E ++ 。 用(; I I = I = H [U] 、P [i])と する場合(!VIS [V = T [I])[V] = F tarjan(V)、U。 以下のための(I = G [U]; I; I = P [I]) { Vの = tが[I]において、X = Sで[V]、Y =T [V]、(X)を見つけます。 もし(D [V] < 0)スワップ(x、y)は、V = - D [V]; 他の V = D [V]。 ANS [V] = MAX(MX [Y] - MI [x]は、MAX([x]は、DW [Y])まで)。 } } インラインボイド GET(INT&A ) { チャーC。 一方、((C = GETCHAR())< ' 0 ' || C> ' 9 ' )。 用(= 0 ; C> = ' 0 ' && C <= ' 9 ' ; C = GETCHAR())は、A = A * 10+ C- ' 0 ' ; } 無効 アウト(INT X) { 場合(X> 9)アウト(X / 10 )。 putchar(Xの%10 + ' 0 ' )。 } INT )(メイン { 用(取得)N(i = 1 ; iが<= N; I ++)を取得(MX [i])と、MI [I] = MX [I]。 以下のために(E = K = 1 ; K <N; ++ k)を取得する(I)、取得し、(J)(I、J、追加0 、H)。 用(取得(M)、K = 1 ; K <= M; ++ k)を取得する(I)、取得し、(J)(I、J、K、Q)を追加します。 tarjan(1 )。 用(i = 1 ; I <= M ++ i)がアウト(ANS [i])と、プット("" )。 リターン 0 ; }