zoukankan      html  css  js  c++  java
  • [HNOI2003] 消防局的设立

    传送门:>HERE<

    题意:给出一颗树,先要求在一些点上设立消防局。每个消防局能够覆盖与它距离不大于2的其他点。求最少设置几个消防局才能够覆盖所有节点。

    解题思路:

      贪心:每次选取还没有被覆盖的深度最大的点,在它的爷爷那里设立消防局。

      为什么这样是正确的呢?这里有一个很巧妙的思路:由于我目前选择的是没有标记的并且是最深的了,所以肯定不存在还没有标记的但比这个点更深的点了(已经被覆盖的点我们肯定不会去浪费机会再设立了)。因此想要覆盖当前这个最深的点,有三个选择:1.设立在它父亲 2.设立在它兄弟 3.设立在它爷爷

      很容易发现,如果设立在了它爷爷那里,一定覆盖了它父亲和它兄弟,因此我们就可以贪心地选择在它爷爷那里设立

    Code

      细节。不知道为什么在洛谷AC了,在BZOJ却CE了

    /*by DennyQi*/
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b))?(a):(b))
    #define  Min(a,b)  (((a)<(b))?(a):(b))
    using namespace std;
    const int MAXN = 1010;
    const int INF = 0x3f3f3f3f;
    inline int read(){
        int x = 0; int w = 1; register char c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x<<3) + (x<<1) + c - '0', c = getchar();
        return x * w;
    }
    struct Node{int idx,deep;}a[MAXN];
    int N,x,ans,T;
    int fa[MAXN],mark[MAXN];
    vector <int> G[MAXN];
    inline bool comp(Node& a, Node& b){ return a.deep > b.deep; }
    void Dfs(int x, int father, int deep){
        int sz = G[x].size(),v;
        fa[x] = father;
        a[++T] = (Node){x, deep};
        for(int i = 0; i < sz; ++i){
            v = G[x][i];
            if(v == father) continue;
            Dfs(v, x, deep+1);
        }
    }
    inline void MarkDown(int u){
        ++ans;
        int sz = G[u].size(),v,__sz;
        mark[u] = 1;
        for(int i = 0; i < sz; ++i){
            v = G[u][i], mark[v] = 1;
            __sz = G[v].size();
            for(int j = 0; j < __sz; ++j) mark[G[v][j]] = 1;
        }
        u = fa[u];
        mark[u] = 1, mark[fa[u]] = 1;
        sz = G[u].size();
        for(int i = 0; i < sz; ++i) mark[G[u][i]] = 1;
    }
    int main(){
    //    freopen(".in","r",stdin);
        N=r;
        for(int i = 2; i <= N; ++i){
            x=r;
            G[i].push_back(x), G[x].push_back(i);
        }
        Dfs(1, 0, 1);
        sort(a+1,a+T+1,comp);
        int u,v,sz;
        for(int i = 1; i <= T; ++i){
            u = a[i].idx;
            if(mark[u]) continue;
            if(fa[fa[u]]) MarkDown(fa[fa[u]]);
            else{
                if(fa[u]) MarkDown(fa[u]);
                else MarkDown(u);
            }
        }
        printf("%d", ans);
        return 0;
    }
  • 相关阅读:
    html标签
    正则表达式判断号码靓号类型
    power函数:求底的n次幂
    php5.3的新特性
    xml方式操作txt文件
    什么是闭包?
    php设计模式单例模式
    面试总结
    统计ip代码
    XSL语言学习
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9380834.html
Copyright © 2011-2022 走看看