标签:dfs 1.0 div article ant ceil mil UI declared
| 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 树的结构+二分
标签:dfs 1.0 div article ant ceil mil UI declared
原文地址:http://www.cnblogs.com/slgkaifa/p/6922470.html