2021.8.13提高B组模拟5T2 Crisis(小根堆)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.13提高B组模拟5T2 Crisis(小根堆)相关的知识,希望对你有一定的参考价值。
Crisis
题目大意
输入样例
1.
3 100
0 0 0
2.
3 50
0 0 0
3.
14 60
0 0 1 1 2 2 2 5 7 5 7 5 7 5
输出样例
1.
3
2.
2
3.
5
解题思路
我们可以先求出:
每个节点需要多少个子节点(直系儿子) 才能向上递交请愿书
例如第三个样例(括号为所最少需要的节点数):
0
(
2
)
0(2)
0(2)
1
(
2
)
2
(
2
)
1(2)2~~(2)
1(2)2 (2)
3
(
0
)
4
(
0
)
5
(
3
)
6
(
0
)
7
(
2
)
3(0)4 ~~(0)5~~(3)6~~(0)7(2)
3(0)4 (0)5 (3)6 (0)7(2)
8
(
0
)
10
(
0
)
12
(
0
)
14
(
0
)
9
(
0
)
11
(
0
)
13
(
0
)
8(0)10(0)12(0)14(0)9(0)11(0)13(0)
8(0)10(0)12(0)14(0)9(0)11(0)13(0)
再跑一遍bfs/dfs(求出它的bfs/dfs序)
从最底端开始遍历节点
如果当前节点有儿子,则在堆中取出前k个数,累加起来,再放入父节点的小根堆中
(k为当前节点最少所需要的节点数)
否则,就直接将 1 1 1放入父节点的小根堆中(因为只有工人是没有儿子的)
AC代码
#include<cstdio>
#include<queue>
using namespace std;
int n,T,t,tot,head,tail;
int f[100005],p[100005],hd[100005],fa[100005],son[100005],need[100005],needson[100005];
struct node
int to,next;
a[100005];
struct work
int x;
bool operator<(const work&a)const
return x>a.x;
;
void add(int x,int y)
a[++tot]=(node)y,hd[x];
hd[x]=tot;
void bfs()//求bfs序
p[++tail]=0;
f[++t]=0;
while(head<tail)
int x=p[++head];
for(int i=hd[x];i;i=a[i].next)
p[++tail]=a[i].to;
f[++t]=a[i].to;
priority_queue<work>q[100005];
int main()
scanf("%d%d",&n,&T);
for(int i=1;i<=n;i++)
int x;
scanf("%d",&x);
add(x,i);
son[x]++;
fa[i]=x;//x的父亲为i
for(int i=0;i<=n;i++)//求出每个节点需要的儿子
if(son[i]==0)need[i]=1;
else
if(son[i]*T%100==0)needson[i]=son[i]*T/100;
else needson[i]=int(son[i]*T/100)+1;
bfs();
for(int i=t;i>=1;i--)//遍历每个节点
int x=f[i];
if(son[x]!=0)
int o=0;
while(o<needson[x])
o++;
work xx=q[x].top();
need[x]+=xx.x;
q[x].pop();
q[fa[x]].push((work)need[x]);
printf("%d",need[0]);
return 0;
谢谢
以上是关于2021.8.13提高B组模拟5T2 Crisis(小根堆)的主要内容,如果未能解决你的问题,请参考以下文章
2021.8.13提高B组模拟5T1 Brothers(暴力)