k半径覆盖问题
题意
一个点可以覆盖半径2以内的的点,最少多少点可以全覆盖(可以延伸为k半径)
预处理出每个点深度,从最深的点开始网上覆盖,dis数组表示最近的覆盖中心点的距离,大于2(k)时,把他的2(k)代设成覆盖中心(贪心思想,保证最远且刚好能覆盖当前点)
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=998244353; const int maxn=500005; int n; int dis[100005],fa[100005],dep[100005],id[100005],ant; bool cmp(int a,int b) { return dep[a]>dep[b]; } int main() { scanf("%d",&n); id[1]=1; dis[0]=dis[1]=maxn; for(int i=2;i<=n;i++) { scanf("%d",&fa[i]); dep[i]=dep[fa[i]]+1; id[i]=i; dis[i]=maxn; } sort(id+1,id+1+n,cmp); for(int i=1;i<=n;i++) { int now=id[i]; int f=fa[now]; int gf=fa[fa[now]]; dis[now]=min(dis[now],dis[f]+1); dis[now]=min(dis[now],dis[gf]+2); if(dis[now]>2) { ant++; dis[gf]=0; dis[fa[gf]]=min(dis[fa[gf]],1); dis[fa[fa[gf]]]=min(dis[fa[fa[gf]]],2); } } printf("%d\n",ant); return 0; }