UVa - 12186 Another Crisis

前言:


水题,还是忍不住用了边表 ……

哈,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 ) ) ;
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值