дп [корень] [у]: корень корня поддерева, чтобы получить число сторон поддерево узлов J необходимости потерять наименьшее, внимание должно быть сохранено в поддерево корневого узла. В противном случае это невозможно дп
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <CString> #include <алгоритм> #include <очереди> #include <вектор> с использованием пространства имен станд; рядный INT чтение () { INT сумма = 0 , х = 1 ; символ ч = GetChar (); в то время как (ч < ' 0 ' || ч> ' 9 ' ) { если (ч == ' - ' ; = GetChar (); } В то время (ч> = ' 0 ' && ч <= ' 9 ' ) { сумма = (сумма << 1 ) + (сумма << 3 ) + (ч ^ 48 ), гл = GetChar (); } Возвращение й сумма: - сумма; } Инлайн недействительными записи ( INT х) { если (х < 0 ) putchar ( ' - ' ), х = - х; если (х> 9 ) записи (х/ 10 ); putchar (х % 10 + ' 0 ' ); } Int миля ( INT х, ИНТ у) { вернуться х <у? х: у; } INT ма ( INT х, INT у) { вернуться х> у? х: у; } Const INT М = 155 ; Const ИНТ инф = 0x3f3f3f3f ; вектор < INT > г [М]; INT дп [М] [М], Num [М], SZ [М]; недействительным ДФС ( INT и) { SZ [и]= 1 ; если (г [и] .size () == 0 ) { дп [и] [ 1 ] = 0 ; SZ [и] = 1 ; вернуться ; } Для ( INT I = 0 ; я <г [и] .size (); я ++ ) { INT v = г [и] [I]; ДФС (v); SZ [и] + = SZ [v]; для ( INT J = SZ [и]; J> = 0 ; j-- ) { для ( Int к = 1 ; к <= J, K ++ ) { дп [и] [J] = т (дп [и] [J], дп [и] [JK] + дп [v] [к] - 1 ); } } } } INT основных () { INT п = следующим образом (), р = следующим образом (); для ( INT I = 0 ; г <= п; я ++ ) для ( INT J = 0 ; J <= р; j ++ ) дп [I] [J] = инф; для ( INT I = 1 ; <п; я ++ ) { INT х, у; х = чтения (); у = следующим образом (); г [х] .push_back (у); Num [х] ++ ; } Для ( INT I = 1 ; г <= п; я ++ ) дп [я] [ 1 ] = Num [I]; ДФС ( 1 ); INT ANS = дп [ 1 ] [р]; для ( INT I = 2 ; г <= п; я ++ ) ANS = мили (ANS, дп [I] [р] + 1 ); написать (ANS); putchar ( ' \ п ' ); вернуться 0 ; }