Given interger N and a tree with N points. To give a definition of a watered point, which has a special point to it in distance 2 or shorter. Please place special points as less as possible, so that each point of them ALL got watered.
Solution 2279
Consider using Greedy Algorithm. First of all, we push all the points in order by their deeps. For each point, we just pull out the deepest unwatered point, and set its grandfather to a special point. That’s the optimal solution.
Don’t forget to double the memory of the array of edges!
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#define reg registerstruct node{int x,y,next;}e[2010];int len=0;int first[1010];int h[1010];int fa[1010];int n;int sd;int ans=0;voidins(int x,int y){
e[++len].x=x;e[len].y=y;
e[len].next=first[x];first[x]=len;}voiddfs(int f,int x,int hi){if(h[x])return;
h[x]=hi;fa[x]=f;for(reg int i=first[x];i;i=e[i].next)dfs(x,e[i].y,hi+1);}struct nod{int id,h;friendbooloperator<(const nod a,const nod b){return a.h>b.h;}}p[1010];int ok[1010];voidset(int x){for(reg int i=first[x];i;i=e[i].next){int y=e[i].y;
ok[y]=1;for(reg int j=first[y];j;j=e[j].next){int z=e[j].y;
ok[z]=1;}}
ok[fa[x]]=1;ok[fa[fa[x]]]=1;for(reg int i=first[fa[x]];i;i=e[i].next){int y=e[i].y;
ok[y]=1;}}voidwork(){for(reg int i=1;i<=n;++i)
p[i]=(nod){i,h[i]};
std::sort(p+1,p+n+1);for(reg int i=1;i<=n;++i){if(ok[p[i].id])continue;++ans;set(fa[fa[p[i].id]]);}}intmain(){memset(first,0,sizeof(first));scanf("%d",&n);for(reg int i=1;i<n;++i){scanf("%d",&sd);ins(i+1,sd);ins(sd,i+1);}memset(h,0,sizeof(h));dfs(1,1,1);work();printf("%d",ans);}