题解:P13918 [PO Final 2024] 雪崩 / Avalanche
第一步是问题转化。
我们知道村庄关系就是一棵树,那么破坏最大化一定是从树根开始雪崩,这样树的大小就是雪崩的破坏程度。而
那么问题就转化成:给定一棵树,删去
求最大值最小问题首先想到二分答案。
不难发现
判断有无解很简单,贪心。记块大小的最大值为
当前子树的大小超过
如果
# include <bits/stdc++.h>
# include <iostream>
using namespace std;
struct Node
{
int to;
struct Node* nxt;
};
struct Head
{
struct Node* nxt;
};
struct Head p[100005];
int siz[100005];
int cnt;
struct Node* ini()
{
struct Node* tmp = (struct Node*) malloc (sizeof(struct Node));
tmp->nxt = NULL;
return tmp;
}
void add_edge(int x,int y)
{
struct Node* tmp1 = ini();
tmp1->to = y;
tmp1->nxt = p[x].nxt;
p[x].nxt = tmp1;
return ;
}
int solve(int u,int k)
{
siz[u] = 1;
for (struct Node* tmp=p[u].nxt;tmp!=NULL;tmp=tmp->nxt)
{
int v = tmp->to;
solve(v,k);
siz[u] += siz[v];
}
if (siz[u] > k)
{
siz[u]=0;
cnt++;
}
return siz[u];
}
int main (void)
{
int n,k;
scanf ("%d %d",&n,&k);
for (int i=1;i<=n;i++)
{
p[i].nxt = NULL;
}
for (int i=1;i<n;i++)
{
int u,v;
scanf ("%d",&u);
v=i+1;
add_edge(u,v);
}
int l=1,r=n;
int ans;
while (l <= r)
{
cnt=0;
int mid = (l+r)/2; // mid是最大破坏值
solve(1,mid);
if (cnt > k) // solve得到的是最大破坏值的情况下最少需要几个围墙
{
l = mid+1;
}
else
{
r = mid-1;
ans = mid;
}
}
printf ("%d",ans);
return 0;
}