[杂题]URAL1822. Hugo II's War

看懂题意的请直接跳过下一坨! 本人有表达障碍!

==========================================

题意: (题意真的很难很难懂啊!!!  去他娘的**)

有一个王国,王国里有一个国王(编号为1),他有(编号为2~n) n-1个臣子(这些臣子并不全和他有直接关系)

然后呢 国王要去打架,但是只有当他的x%个及以上的直系下属(与他有直接关系的臣子)做好打架的准备了,他才能去打架

他的直系下属也有下属,也要其中x%及以上的下属做好打架准备了,那些直系下属才会开始准备打架...直到最后一层下属(也就是没有下属的那些人)他们会直接开始准备打架

当然 (除了国王)所有臣子准备打架都需要时间ti;

有一个上限时间T 臣子们准备的总时间不能超过T

给的是n(包括国王 共n个人(国王加臣子)),T

接下来是编号2~n的臣子们的信息(1号是国王) pi和ti

pi代表该臣子是   编号为pi的人  的下属

ti代表该臣子      准备打架需要的时间

问的是: 不超过T的情况下,准备战斗的臣子要尽量多,求x的最大值

是不是看了这么大一坨还是不知道讲什么...

那么我们来看个案例:

6 3
1 2
2 2
2 1
1 2
1 4

n=6 T=3 就是1个国王 5个臣子 臣子们要在3单位时间内准备好打架接着
2号:1 2
3号:2 2
4号:2 1
5号:1 2
6号:1 4

他们的关系图是这样的:

这些人中 3、4、5、6都是没有下属的 因此都可以直接开始准备打架

如果x是100,那么就是需要100%以上的下属完成准备,也就是当3、4完成2才能开始 ;当2、5、6完成1才能去打架

    (3、4、5、6同时开始准备,3、4都完成过去了2天, 也就是第三天2可以开始准备(此时5也完成了),然后过了4天2、5、6都完成,1就可以去打架了,所以x==100时总共用了4天)

如果x是50,那么就是需要50%以上的下属完成准备,也就是当3或4完成 2才能开始 ;当2、5、6中有2个人(ceil(3/2)=2)完成 1才能去打架

    (3、4、5、6同时开始准备,第一天结束4完成,此时已经满足“2号的50%及以上的下属完成”,于是2开始准备,第2天结束,2准备完成,此时5也完成了,这样就满足了“1号的50%及以上的下属完成”,1就可以去打架了,所以x==50时总共用了2天)

题目的上限T==3也就是必须要在3天内完成准备 显然x==100的时候需要4天不满足,而x==50的时候需要2天,满足。

=================================================

呃 到这里 才讲完题目...

好了 那么怎么做呢?

我们先倒着思考,要是我们已知x(百分比),继而来判断能不能满足“准备天数<=上限天数T”的条件 是不是就简单了很多呢,只要傻傻的相加就好了呢o(^▽^)o

好 那么我们就来枚举每一个百分比能不能满足条件 然后找个最大的!

浮点误差是1e-4那么0到100就总共1e6个情况,然后每个情况都要判断,最坏要加1e4次(n上限1e4)

那么就是O(1e4*1e6),Time Limit:500ms

啊哦不够额 ( ̄▽ ̄)

那就二分呗~~上下限分别是0和100,结束的条件就是 fabs(l-r)<1e4 咯~~

然后就结束了...

然后一交WA *****

坑爹的居然要LL

时间上限T明明只有1e6,ti明明只有100,1e4个100加起来也才1e6嘛!为什么要LL!

对啊!!写这么大一坨就是为了吐槽一个LL啊!

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const double eps=1e-4;
 5
 6 vector<LL> son[10005], tmp, tot;
 7 int a[10005];
 8 LL sum[10005];
 9
10 int main()
11 {
12     int n, t;
13     scanf("%d%d", &n, &t);
14     for(int i=2;i<=n;i++)
15     {
16         int x;
17         scanf("%d%d",&x,&a[i]);
18         son[x].push_back(i);
19     }
20     a[1]=0;
21     double l=0, r=100, ans;
22     while(fabs(l-r)>=eps)
23     {
24         double m=(l+r)/2.0;
25         memset(sum, -1, sizeof(sum));
26         tmp.clear();
27         tmp.push_back(1);
28         while(!tmp.empty())
29         {
30             int p=tmp[tmp.size()-1];
31             if(!son[p].size())
32                 sum[p]=a[p], tmp.pop_back();
33             else
34             {
35                 if(sum[son[p][0]]==-1)
36                 {
37                     for(int i=0;i<son[p].size();i++)
38                         tmp.push_back(son[p][i]);
39                     continue;
40                 }
41                 tot.clear();
42                 for(int i=0;i<son[p].size();i++)
43                     tot.push_back(sum[son[p][i]]);
44                 sort(tot.begin(), tot.end());
45                 int pp;
46                 for(int i=0;i<son[p].size();i++)
47                     if((i+1)*100.0/son[p].size()>=m)
48                     {
49                         pp=i;
50                         break;
51                     }
52                 sum[p]=tot[pp]+(LL)a[p];
53                 tmp.pop_back();
54             }
55         }
56         if(sum[1]<=t)
57             ans=m, l=m;
58         else
59             r=m;
60     }
61     printf("%.7lf\n", ans);
62     return 0;
63 }

URAL 1822

[杂题]URAL1822. Hugo II's War

时间: 2024-08-06 07:57:44

[杂题]URAL1822. Hugo II'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

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

【最小生成树杂题】

这里谈一下最小生成树 生成树的概念:连通图G的一个子图如果是一棵包含G的所有顶点的树,则该子图称为G的生成树.生成树是连通图的极小连通子图.所谓极小是指:若在树中任意增加一条边,则将出现一个回路:若去掉一条边,将会使之变成非连通图. 生成树各边的权值总和称为生成树的权.权最小的生成树称为最小生成树. 最小生成树一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.常用于求最小生成树得算法包括kruskal(克鲁斯卡尔)算法或Prim(

_杂题_

杂题集 是个放题的好地方! **** 5.28 **** - BZOJ [3052] 糖果公园 - 据说是一道区间操作的综合题,但现在貌似蹦了? 现在还是太水,之后再来写吧. *************

hdu 3641 数论 二分求符合条件的最小值数学杂题

http://acm.hdu.edu.cn/showproblem.php?pid=3641 学到: 1.二分求符合条件的最小值 /*==================================================== 二分查找符合条件的最小值 ======================================================*/ ll solve() { __int64 low = 0, high = INF, mid ; while(low <=

hdu 4961 数学杂题

http://acm.hdu.edu.cn/showproblem.php?pid=4961 先贴个O(nsqrtn)求1-n所有数的所有约数的代码: vector<int>divs[MAXN]; void caldivs() { for(int i=1;i<MAXN;i++) for(int j=i;j<MAXN;j+=i) divs[j].push_back(i); } 有了这个当时理下思路就可写了,但是重复数处理注意: 1.用一个数组vis[]  vis[i]=1表示i存在

poj 杂题 - 1959 Darts

这一题放在杂题里,是因为我没有用DP,而是使用的枚举,当然是受到了discuss里面的启发. 因为我们只能有三次机会,每一次只可以是固定的63个数,所以枚举感觉更加直观,但是不知道是不是没有DP快. #include<stdio.h> #include<string.h> int n; int Darts[63]; int main(){ int t,c=1,i,j,k,res; scanf("%d",&t); for(i = 0 ;i<=20;i

poj 杂题 - 2081 Recaman&#39;s Sequence

这道题目一开始就能知道考点在如何缩短查找时间.所以加快查找是我们的重点.但是在大数据面前,查找算法都不够快,所以我们用简单的hash思想来做. 我们开一个数组a,当出现了一个数b时,把该数作为下标调整值,即a[b] = -1,下一次出现该值的时候直接去找这个值作为下标的a值是否为-1即可. #include<stdio.h> #include<string.h> #define MAX 5000010 int p[MAX]={0}; int s[MAX]={0}; int main

杂题选录

LuoguP3948数据结构 10-20 是比较裸的差分题目,但是要注意在线查询的时候开始傻了,每次都暴力地从1到n搞一遍,还存在数组中每次都要清空...结果T了很多点. 其实在线查询的时候直接用变量+扫到r就行了. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 5 using namespace std; 6 typedef long long ll; 7 8 int n,opt,tot,