题目链接
题目链接是洛谷有题意翻译的
题意:
给你一个n个点的图,每个点有一个通往的点,要求你修改若干点的通往的点,使得每个点在走k步后都在1号点,改后可以有自环,求最少修改次数。
题解:
与某ZR的曾经一场考试的题撞题了,于是发现某ZR曾经的考试搬了原题。
首先我们会发现,1号点应该指向自己,这样我们才能保证其他点走到1号点之后不会再走出去。
然后我们会考虑贪心,设1是根,从深度大的向深度小的找,然后记录当前的点到子树内最深的点的距离,如果到了k,那么就把当前点接到根,还有一些加一减一之类的细节,就不具体说了。
代码:
#include <bits/stdc++.h>
using namespace std;
int n,k,hed[100010],cnt,ans,dis[100010],fa[100010];
struct node
{
int to,next;
}a[200010];
inline void add(int from,int to)
{
a[++cnt].to=to;
a[cnt].next=hed[from];
hed[from]=cnt;
}
inline void dfs(int x)
{
dis[x]=1;
for(int i=hed[x];i;i=a[i].next)
{
int y=a[i].to;
if(y==fa[x])
continue;
fa[y]=x;
dfs(y);
dis[x]=max(dis[x],dis[y]+1);
}
if(dis[x]>=k&&fa[x]>1)
{
dis[x]=0;
++ans;
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
{
int x;
scanf("%d",&x);
if(i==1)
{
if(x!=1)
++ans;
}
else
add(x,i);
}
dfs(1);
printf("%d\n",ans);
return 0;
}