您的位置:首页 > 其它

bzoj1217: [HNOI2003]消防局的设立(贪心)

2017-12-04 13:13 369 查看
题目传送门

这不是洛谷的弱化版么。。

好水。。

解法:

显然的贪心呀。

把1弄做根。

然后搞出每个点的深度。

那么肯定从边边开始染呀。

然后对于每个边边的点,不用考虑他下面的点了。

然后把他的爷爷设立为消防局就完了呀。

代码实现:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct node {int x,y,next;}a[2100];int len,last[1100];
struct edge {int x,dep;}tr[1100];int fa[1100];
void ins(int x,int y) {len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;}
void dfs(int x) {
for(int k=last[x];k;k=a[k].next) {
int y=a[k].y;
if(y!=fa[x]) {fa[y]=x;tr[y].dep=tr[x].dep+1;dfs(y);}
}
}
bool v[2100];
void fg(int x,int d,int f) {
if(d>2)return ;v[x]=true;
for(int k=last[x];k;k=a[k].next) {
int y=a[k].y;
if(y!=f)fg(y,d+1,x);
}
}
bool cmp(edge n1,edge n2){return n1.dep>n2.dep;}
int main() {
int n;scanf("%d",&n);len=0;memset(last,0,sizeof(last));
for(int i=2;i<=n;i++) {int x;scanf("%d",&x);ins(i,x);ins(x,i);}
for(int i=1;i<=n;i++)tr[i].x=i;
tr[1].dep=0;fa[1]=0;dfs(1);sort(tr+1,tr+1+n,cmp);
memset(v,false,sizeof(v));int ans=0;
for(int i=1;i<=n;i++)if(v[tr[i].x]==false){ans++;fg(tr[i].dep<2?1:fa[fa[tr[i].x]],0,0);}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: