消防局的设立

Posted zzctommy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消防局的设立相关的知识,希望对你有一定的参考价值。

主要思路:贪心,从叶子节点开始(按深度排序即可做到),从它父亲的父亲,把距离不超过 (2) 的节点都打上标记,(ans++)。这样一定最优,因为必须覆盖那个没被覆盖的节点。注意把根节点的父亲设为根节点,否则从根节点开始跳就RE了

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,ans;
bool vis[N];
vector<int>g[N];
int p[N];
struct node2{
    int depth,id;
}d[N];
bool cmp(node2 a,node2 b)
{
    return a.depth>b.depth;
}
void dfs1(int now,int deep,int fa)
{
    d[now].depth=deep;
    p[now]=fa;
    for(int i=0;i<g[now].size();i++)
    {
        if(g[now][i]==fa) continue;
        dfs1(g[now][i],deep+1,now);
    }
}
void era(int now,int dis,int fa)
{
    if(dis>2)return;
    vis[now]=true;
    for(int i=0;i<g[now].size();i++)
    {
        if(g[now][i]!=fa)era(g[now][i],dis+1,now);
    }
}
int main()
{
    scanf("%d",&n);
    p[1]=1;
    d[1].id=1;
    d[1].depth=1;
    for(int i=2;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        d[i].id=i;
        g[x].push_back(i);
        g[i].push_back(x);
    }
    dfs1(1,1,1);
    sort(d+1,d+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        if(vis[d[i].id])continue;
        int grand=p[p[d[i].id]];
        era(grand,0,grand);
        ans++;
    }
    printf("%d
",ans);
    return 0;
}

以上是关于消防局的设立的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1217: [HNOI2003]消防局的设立

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

消防局的设立

[HNOI2003]消防局的设立

[HNOI 2003]消防局的设立

[HNOI2003]消防局的设立