DP [ルート] [J]:サブツリーのルートのルートは、サブツリーのルートノードに保持されなければならない少なくとも、関心を失うサブツリー・ノードjのニーズの辺の数を取得します。それ以外の場合は、DPは不可能です
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> 書式#include <キュー> の#include <ベクトル> 使用して 名前空間はstd; インラインint型リード(){ int型の和= 0、X = 1 。 チャー CH = GETCHAR()。 一方、(CH < ' 0 ' || CH> ' 9 ' ){ 場合(CH == ' - ' ) X = 0 。 = GETCHAR()。 } 一方、(CH> = ' 0 ' && CH <= ' 9 ' ){ 合計 =(合計<< 1)+(和<< 3)+(CH ^ 48)、CH = GETCHAR()。 } 戻りのx合計: - ?合計。 } インラインボイド書き込み(INT X){ 場合(X < 0 ) のputchar(' - ')、X = - X。 もし(X> 9 ) ライト(X/ 10 )。 putchar(Xの%10 + ' 0 ' )。 } int型 MI(int型のx、int型のy)を{ 返す X <Yを?X:Y。 } int型 MA(int型のx、int型のY){ 戻り X> Yの?X:Y。 } のconst int型 M = 155 。 const int型 INF = 0x3f3f3f3f 。 ベクター < INT > G [M]。 INT DP [M] [M]、NUM [M]、SZ [M]。 空隙 DFS(INT U){ SZ [U] = 1 。 もし(G [U] .size()== 0 ){ DP [U] [ 1 ] = 0 ; SZ [U] = 1 。 返します。 } のために(int型 i = 0 ; I <G [U] .size(); iは++ ){ int型、V = G [U] [I]。 DFS(V); SZ [U] + = SZ [V]。 用(INT J = SZ [U]; J> = 0 ; j-- ){ ための(int型 K = 1 ; K <= J kは++ ){ DP [U] [j]は MI =(DP [U] [j]を、DP [U] [JK] + DP [V] [K] - 1 )。 } } } } int型(メイン){ int型 N =(読み取り)、P = 読み取ります(); 以下のために(int型 i = 0 ; iは= <N; I ++ ) のための(INT J = 0 ; J <= P; J ++ ) DP [I] [J] = INF。 以下のために(int型 i = 1 ; iがn <; iは++ ){ int型X、Y。 X = read()は、リード()。 Y = G [X] .push_back(Y)。 NUM [X] ++ ; } のために(int型 I = 1 iが++; iが<= N ) DP [I] [ 1 ] = [I] NUM。 DFS(1 )。 INT ANS = DP [ 1 ] [P]。 以下のために(int型 I = 2 ; iが<= N; iは++ ) ANS = MI(ANS、DP [I] [P] + 1 )。 (ANS)を書きます。 putchar(' \ nを' ); リターン 0 ; }