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 ≤ 104;
0 ≤ t ≤ 106). 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 thei-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;
}
 

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

时间: 2024-10-12 23:37:08

URAL 1822. Hugo II&#39;s War 树的结构+二分的相关文章

URAL 1822. Hugo II&#39;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

[杂题]URAL1822. Hugo II&#39;s War

看懂题意的请直接跳过下一坨! 本人有表达障碍! ========================================== 题意: (题意真的很难很难懂啊!!!  去他娘的**) 有一个王国,王国里有一个国王(编号为1),他有(编号为2~n) n-1个臣子(这些臣子并不全和他有直接关系) 然后呢 国王要去打架,但是只有当他的x%个及以上的直系下属(与他有直接关系的臣子)做好打架的准备了,他才能去打架 他的直系下属也有下属,也要其中x%及以上的下属做好打架准备了,那些直系下属才会开始准备

Android无限级树状结构

通过对ListView简单的扩展.再封装,即可实现无限层级的树控件TreeView. 1 package cn.asiontang.nleveltreelistview; 2 3 import android.annotation.TargetApi; 4 import android.content.Context; 5 import android.os.Build; 6 import android.util.AttributeSet; 7 import android.view.View

ZOJ 3635 树状数组+二分

这题那时怎么想就是想不出来--而且今晚没有多大状态,自己都晕了--一题没做出来-- baoge解释好久才懂--唉--线段树,树状数组用得还是不够熟啊-- WA了二发,才知道二分错了,二分好久不用,老是出错了现在-- #include<iostream> #include<cstring> #include<string> #include<cstdio> #define sca(a) scanf("%d",&a) #define

hdu4729 树链剖分+二分

An Easy Problem for Elfness Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 1235    Accepted Submission(s): 257 Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans t

POJ 2828 Buy Tickets (线段树 or 树状数组+二分)

题目链接:http://poj.org/problem?id=2828 题意就是给你n个人,然后每个人按顺序插队,问你最终的顺序是怎么样的. 反过来做就很容易了,从最后一个人开始推,最后一个人位置很容易就确定了,那最后第二个人的位置也可以推(与最后一个人的位置无关)...依次就都可以确定所有的人了. 用前缀和的思想,要是这个人的位置确定了,那么就标记这个人位置的值为0,然后回溯更新,跟求逆序对个数的思想比较类似. 线段树: 1 #include <iostream> 2 #include &l

HDU 2852 KiKi&#39;s K-Number【 树状数组 二分 】

题意:给出m个操作,0:是增加一个数,add(x,1)1:是删除一个指定的数,这个是看sum(x) - sum(x-1)是否为0,为0的话则不存在,不为0的话,则add(x,-1)2:是查询比x大的数中第k大的数,先求出比x小的个数s,假设比x大的数中第k大的数为y,那么比y小的个数有s+k个二分y的值来找 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath&g

TOJ 4602:高桥和低桥(二分或树状数组+二分)

描述 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算"淹了两次".举例说明:假定高桥和低桥的高度分别是5和2,初始水位为1第一次洪水:水位提高到6(两个桥都被淹),退到2(高桥不再被淹,但低桥仍然被淹)第二次洪水:水位提高到8(高桥又被淹了),退到3.没错,文字游戏.关键在于"又"的含义.如果某次洪水退去之后一座桥仍然被淹(即水位不小于

HDU 2852 KiKi&#39;s K-Number (树状数组 &amp;&amp; 二分)

题意:给出对容器的总操作次数n, 接下来是这n个操作.这里对于一个容器提供三种操作, 分别是插入.删除和查找.输入0  e表示插入e.输入1  e表示删除e,若元素不存在输出No Elment!.输入2  e  k表示查找比e大且第k大的数, 若不存在则输出Not Find! 分析:这里考虑树状数组做的原因是在第三个操作的时候, 只要我们记录了元素的总数, 那通过求和操作, 便能够高效地知道到底有多少个数比现在求和的这个数要大, 例如 tot - sum(3)就能知道整个集合里面比3大的数到底有