AT2044 Teleporter

传送门

这个是真的简单题,随便手玩一下就可以发现最优策略一定是给\(1\)加上自环
然后就可以dfs一下看哪些点子树里深度最深的点到当前点的距离会等于\(k-1\),然后将当前点连向\(1\)(当然特判一下父亲节点是不是\(1\)),就好了
代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
void read(int &x) {
	char ch; bool ok;
	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1e5+10;bool vis[maxn];
int n,k,dep[maxn],ans,f[maxn],cnt,pre[maxn*2],nxt[maxn*2],h[maxn];
void add(int x,int y){pre[++cnt]=y,nxt[cnt]=h[x],h[x]=cnt;}
void dfs(int x){
	vis[x]=1;
	for(rg int i=h[x];i;i=nxt[i])
		if(!vis[pre[i]])dfs(pre[i]),dep[x]=max(dep[pre[i]]+1,dep[x]);
	if(dep[x]>=k-1&&f[x]!=1)dep[x]=-1,ans++;
}
int main()
{
	read(n),read(k);scanf("%d",&f[1]);
	for(rg int i=2;i<=n;i++)read(f[i]),add(f[i],i);
	if(f[1]!=1)ans++,f[1]=1;dfs(1);
	printf("%d\n",ans);
}
posted @ 2019-04-22 14:01  蒟蒻--lichenxi  阅读(146)  评论(0编辑  收藏  举报