URAL 1822. Hugo II's War 树的结构+二分


1822. Hugo II's War

Time limit: 0.5 second
Memory limit: 64 MB
The glorious King Hugo II has declared a war—a war that is holy, victorious, almost bloodless, but ruinous!
Right after declaring the war the king has started summoning the army. He plans to send a recruitment order to all his immediate vassals, who will send the order to their vassals, and so on. In the end, every nobleman of the kingdom will be involved in the preparation for the war.
As soon as a nobleman who has no vassals receives the order, he immediately begins recruiting soldiers and joins his overlord in a few days. If a nobleman has vassals, he waits until there are at least  x% of his immediate vassals ready for the war, then summons his own troops and also joins his overlord. The glorious King Hugo II will go the war as soon as at least  x% of his immediate vassals are ready.
King Hugo II wants to state the number  x in his recruitment order. The king needs as many soldiers as possible for his military campaign. However, if the recruitment takes more than  t days, the enemy may learn about the imminent intrusion and strike first. Help Hugo II find the maximal possible value of  x.

Input

The first line contains the number  n of noblemen in the kingdom and the maximal number of days  tthat can be spent for summoning the army (1 ≤  n ≤ 10 4; 0 ≤  t ≤ 10 6). The noblemen are numbered from 1 to  n. King Hugo II has number 1, and the noblemen with numbers from 2 to  n are described in the following  n − 1 lines. The  i-th of these lines describes the nobleman with number  i and contains integers  pi and  ti, where  pi is the number of his overlord and  ti is the number of days the i-th nobleman will need to summon his troops (1 ≤  pi ≤  n; 0 ≤  ti ≤ 100).

Output

Output the maximal possible value of  x with absolute error at most 10 −4.

Sample

input output
6 3
1 2
2 2
2 1
1 2
1 4
50.00000000




题意:

输入 n 个人,3是表示有多少时间让编号1 的人召集人马。

然后按2到n 的编号 输入pi 和ti。分别是那个人直接 领主,和召集自己本部的人所需的时间。 编号1 是大领主 。 假设 每个领主都只能在 直属下属 有≥x% 的人召齐了人马才可以开始招自己的人。 问x最大是多少,可以让大领主在 t 的时间内 召齐自己的人出发打仗。


做法:

二分x,判断下这个x能否在所需时间内召齐人马。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <string>
#include <iostream>
#include <algorithm>
using namespace std; 
#include <vector> 

long long p[10010],t[10010];
long long nowt[10010];
long long pai[100010];
double x;
long long sum_t;
vector <long long >son[10010];


void dfs(long long nod)
{
	if(son[nod].size()==0)
	{
		nowt[nod]=t[nod];
		return ;
	}
	for(long long i=0;i<son[nod].size();i++) 
		dfs(son[nod][i]); 

	long long need=ceil(1.0*son[nod].size()*x/100.0);//找到所需的最少人数是多少
	for(long long i=0;i<son[nod].size();i++) 
		pai[i]=nowt[son[nod][i]]; 
	
	sort(pai,pai+son[nod].size());
	
	long long ret;
	if(need==0)
		ret=0;
	else
		ret=pai[need-1]; //手下的人中,花费最长时间的那个人
	
	nowt[nod]=ret+t[nod];
}


long long deal()
{
	dfs(1); 
	if(nowt[1]>sum_t)
		return 0;
	else
		return 1;

}
int main()
{  
	long long n;
	while(scanf("%I64d%I64d",&n,&sum_t)!=EOF)
	{
		for(long long i=1;i<=n;i++)
			son[i].clear();
		for(long long i=2;i<=n;i++)
		{
			scanf("%I64d%I64d",p+i,t+i); 
			son[p[i]].push_back(i);
		} 

		double l=0,r=100;//
		double mid;
		while(abs(r-l)>0.0001)
		{
			mid=(l+r)/2.0;
			x=mid;
			if(deal()==0)//所需时间大于 sum_t
				r=mid;
			else
				l=mid;
		} 
		printf("%.7lf\n",l); 
	}
	return 0;
}
 





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值