洛谷 P2279 [HNOI2003]消防局的设立

题目描述
2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地。起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构。如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d。
由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局。消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾。
你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在发生火灾时,消防队有能力及时扑灭火灾。
输入格式 输入文件名为input.txt。
输入文件的第一行为n (n<=1000),表示火星上基地的数目。接下来的n-1行每行有一个正整数,其中文件第i行的正整数为a[i],表示从编号为i的基地到编号为a[i]的基地之间有一条道路,为了更加简洁的描述树状结构的基地群,有a[i]<i。
输出格式 输出文件名为output.txt
输出文件仅有一个正整数,表示至少要设立多少个消防局才有能力及时扑灭任何基地发生的火灾。
输入输出样例 输入 #1
6
1
2
3
4
5
输出 2

分析这道题,不难发现
我们每次可以选取一个深度最深的点,之后把他爷爷放入消防站,暴力贪心~~(注意一下二次染色的计数操作emmm好久不打有点生)
上代码

#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
int n,ans;
int fa[10005];
int ffa;
int tot,head[10005],nex[10005],to[10005];
bool vis[10005];
int depth[1005];
struct NODE {
   
	int depth,fa,biao; 
}d[10005];
inline int read(){
   
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
   ch=getchar();if(ch=='-')f=-1;}
	while(ch>='0'&&ch<='9'){
   x=x*10+ch-'0';ch=getchar();}
	return x*f; 
}
inline void add(int x,int y){
   
	++tot;
	nex[tot]=head[x];
	to[tot]=y;
	head[x]=tot;
}
void dfs(int dian,int father,int dep){
   
	d[dian].depth=dep;
	d[dian].fa=father;
	depth[dian]=dep;
	fa[dian]=father;
	for(int i=head[dian];i;i=nex[i]){
   
		if(to[i]==father) continue;
		dfs(to[i],dian,dep+1);
	}
}
inline bool cmp(NODE a,NODE b){
   
	return a.depth>b.depth;
}
inline void solve(int x,int ti){
   
	if(!ti) return ;
	for(int i=head[x];i;i=nex[i]){
   
		vis[to[i]]=1;
		solve(to[i],ti-1);
	}
}
int main(){
   
	n=read();
	fa[1]=1;
	for(int i=2;i<=n;i++){
   
		int x;
		x=read();
		add(i,x);add(x,i);
	}
	fa[1]=1;
	dfs(1,0,1);
	for(int i=1;i<=n;i++)
	d[i].biao=i,d[i].depth=depth[i];
	sort(d+1,d+n+1,cmp);
	for(int j=1;j<=n;j++){
   
		int biao=d[j].biao;
		if(!vis[biao]){
   
			int fg=fa[fa[biao]];
			vis[fg]=1;
			solve(fg,2);
			ans++;
		}
	}
	cout<<ans;
	return 0;
} 
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务