トピックスアドレスします。https://vjudge.net/contest/363381#problem/F
リファレンスソリューション:
https://blog.csdn.net/starlet_kiss/article/details/104844691
フェンウィックツリーソリューション
https://www.cnblogs.com/cjtcalc/p/12485536.html
DFSソリューション
この質問は、約されていない最適解の最小接続部分グラフを計算することである、何の根
これら二つのアプローチを取って、私のコード:
// の#include <ビット/ STDC ++ H> の#include <iostreamの> する#include <cstdioを> する#include < 文字列・H> の#include <アルゴリズム> 使用して 名前空間STDを、 const int型 MAXX = 200100 ; INTエッジ[MAXX << 1 ]、ETO [MAXX << 1 ]、頭部[MAXX << 1 ]。 INT 色[MAXX]和[MAXX]、ANS [MAXX]、FU [MAXX]。 INT TOT = 0 、N。 int型のread(){ / * INT X = 0、F = 1。 チャーS = GETCHAR()。 一方、(S <0 || S> 9){IF(S == ' - '){= -f F; S = GETCHAR();}} (S> = 0 && S <= 9){; S = GETCHAR()X = X * 10の+ S-'0' }ながら リターンX * F。 * / チャー X = GETCHAR()。 一方、(x == ' ' || X == ' \ n ')x = GETCHAR()。// もし(x == ' 0 ') のリターン - 1 。 それ以外の 場合(X == ' 1 ')の戻り 1 ; それ以外 の戻り 0 ; } ボイド追加(INT U、INT V){ //エッジにETO隣接ノードは、このノードの親ノードのエッジノード ETO [TOT ++] =頭部[U]、エッジ[TOT = V、ヘッド[U] = TOT; } ボイド DFS (INT U、INT {F) FU [U] = ; F SUM [U] = ;色[U] のために(INT ; I> Iは、ヘッド[U] = 0 ;私は= {ETO [I]) INTを =にエッジ[I]は、 IF(== Fまで)続行; (に、U)DFS; IF(SUM>へ] 0)SUM [U] + = SUM [する]; } } 無効DFS(INT U、INT F){ 場合(和は[U]> = 0)[U] = ANS MAX(和[U]、[F]をANS)。 他の 場合(ANS [F]> 0 + [F] [U] = ANS ANS)[U]和。 他の ANS [U] = 合計[U]; 以下のために(INT iはヘッド= [U]; I> 0 ; iが= {ETO [i])と INTを =にエッジ[I]; もし(== F)は継続。 DFS(U、に); } } int型のmain(){ scanf関数(" %のD "、&N) memsetの(頭、0、はsizeof(ヘッド)); // <string.hの> のための(INT I = 1 ; I <= N; I ++ ){ カラー[I] = リード(); } int型A、B、 のために(INT I = 1 ; I <N-; I ++ ){ scanfの(" %D%D "、&A&B)、 追加(A、B)、 追加(B、A); // 側メモリを二回、倍多くのスペースとして必要 } ANS [ 0 ] = SUM [ 0 ] = - 1。 * MAXX、 DFS(1、0 ); ANS [ 1 ] =和[ 1 ]。 DFS(1、0 ); 以下のために(INT iが= 1 ; I <= N; I ++){のprintf(" %dの" 、ANS [I]);} のprintf(" \ nは" ); リターン 0 ; }