前言:
水题,还是忍不住用了边表 ……
哈,Memset(),T 到死 ……
改用 Vector,Ac 。
思路:
如果要 u 签字,那么其下属必须要通过(T * son [ u ] . size - 1)/ 100 + 1 。
但是要直属下属签字,我们可以贪心,如果只要直属下属人数达到通过数,那么一定选择需要直属下属的直属下属签字的人最少的,这个求出每一个直属下属的需要其子树中工人签字的最小人数可以递归实现 。而选择当前直属下属的操作可以用 sort()。从小到大贪心 。
代码:
#include <bits/stdc++.h>
#pragma GCC optimize(2)
const int N = 100000 + 5 ;
std :: vector < int > son [ N ] ;
int n , m , x , T , du [ N ] , root ;
int dfs ( int u ) {
int num = son [ u ] . size ( ) , ans = 0 ;
if ( son [ u ] . empty ( ) ) return 1 ;
std :: vector < int > tmp ;
for ( int i = 0 ; i < son [ u ] . size ( ) ; i ++ )
tmp . push_back ( dfs ( son [ u ] [ i ] ) ) ;
int k = ( T * num ) / 100 + 1 ;
sort ( tmp . begin ( ) , tmp . end ( ) ) ;
for ( int i = 0 ; i < k ; i ++ )
ans += tmp [ i ] ;
return ans ;
}
void init ( ) {
for ( int i = 0 ; i <= N - 4 ; i ++ )
son [ i ] . clear ( ) ;
}
int main ( ) {
while ( 1 ) {
scanf ( "%d%d" , & n , & T ) ;
if ( n == 0 && T == 0 ) return 0 ;
init ( ) ;
for ( int i = 1 ; i <= n ; i ++ ) {
scanf ( "%d" , & x ) ;
son [ x ] . push_back ( i ) ;
}
printf ( "%d\n" , dfs ( root ) ) ;
}
}