BZOJ 1217 [HNOI2003]消防局的设立

题解:贪心,每次选深度最大的未被覆盖节点,在他的2级祖先处放一个

不会DP做法QWQ

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100009;

int n;

int ans=0;

int cntedge;
int head[maxn];
int to[maxn<<1],nex[maxn<<1];
void Addedge(int x,int y){
	nex[++cntedge]=head[x];
	to[cntedge]=y;
	head[x]=cntedge;
}


int father[maxn];
int dep[maxn];
int vis[maxn];
void Minit(){
	memset(head,0,sizeof(head));
	memset(dep,0,sizeof(dep));
	memset(father,0,sizeof(father));
	memset(vis,0,sizeof(vis));
	cntedge=0;
}
void Dfs(int now,int fa){
	father[now]=fa;
	dep[now]=dep[fa]+1;
	for(int i=head[now];i;i=nex[i]){
		if(to[i]==fa)continue;
		Dfs(to[i],now);
	}
}
void C(int x,int fa,int d){
	vis[x]=1;
	if(d==0)return;
	for(int i=head[x];i;i=nex[i]){
		if(to[i]==fa)continue;
		C(to[i],x,d-1);
	}
}

int p[maxn];
int cmp(const int &rhs1,const int &rhs2){
	return dep[rhs1]>dep[rhs2];
}

int main(){
	scanf("%d",&n);
	Minit();
	for(int i=2;i<=n;++i){
		int x;scanf("%d",&x);
		Addedge(x,i);
		Addedge(i,x);
	}
	
	Dfs(1,0);
	for(int i=1;i<=n;++i)p[i]=i;
	sort(p+1,p+1+n,cmp);
	
	for(int i=1;i<=n;++i){
		if(vis[p[i]])continue;
		++ans;
		if(father[father[p[i]]]==0)break;
		C(father[father[p[i]]],0,2);
	}
	
	cout<<ans<<endl;
	return 9;
}

  

posted @ 2018-02-20 11:17  ws_zzy  阅读(76)  评论(0编辑  收藏  举报