以下代码中初始化时不能写 INT_MAX 因为 distan[w]+1、2 会爆
#include <bits/stdc++.h>
using namespace std;
const int MAXN{ 2000+10 };
int father[MAXN], deep[MAXN];
int distan[MAXN]; //从 1 开始, distan 记录 i 到最近消防站的距离
bool cmp(int x, int y){return deep[x]>deep[y];};
int main() //解决半径为 k 的最小覆盖问题
{
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(false);
int self[MAXN]{};//self记录贪心顺序 (从大到小)
int n,ans=0;
cin>>n;
self[1]=1;
distan[1]=distan[0]=MAXN;
for (int i=2;i<=n;i++) //建树, 有 a[i] < i , i 行, a[i] 为键入数字
{
cin>>father[i];
deep[i]=deep[father[i]] + 1;
self[i]=i;
distan[i]=MAXN;
}
sort( self+1 , self+n+1 , cmp ); //保证按顺序遍历
for (int i=1;i<=n;i++) //判断点是否被覆盖
{
int u,v,w;
v=self[i] /*当前位置*/ , w=father[v] , u=father[father[v]];
distan[v]=min( distan[v] , min(distan[w]+1, distan[u]+2) ); //左半部分判断子孙是否覆盖自己,右半部分判断父亲与祖父是否覆盖自己
if (distan[v]>2)
{
distan[u]=0; //设消防站
ans++;
distan[father[u]]=min(distan[father[u]] ,1); //左半部分排除兄弟,标记父亲距离
distan[father[father[u]]]=min(distan[father[father[u]]],2); //如上,标记祖父距离
}
}
cout << ans ;
}