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

题目传送门
这不是洛谷的弱化版么。。
好水。。

解法:
显然的贪心呀。
把1弄做根。
然后搞出每个点的深度。
那么肯定从边边开始染呀。
然后对于每个边边的点,不用考虑他下面的点了。
然后把他的爷爷设立为消防局就完了呀。

代码实现:

#include
#include
#include
#include
#include
#include
#include
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;
}

你可能感兴趣的:(BZOJ,杂)