• 题解 P3942 将军令


    题解

    首先看到这题 (k=1) 时,就是一道 小胖守皇宫,那么由 (k=1) 联想到 (k=2...20) 发现可以树形 (DP)

    但转移方程太难想,不太适合考场做。

    考虑贪心:

    对所有节点先按深度由大到小排序,对于每一个未覆盖的节点,我们选择他的第 (k) 级祖先。

    证明:

    对于一个节点,我们选他的第 (k) 级祖先,这样布置可以覆盖最大的范围,同时因为我们是按深度在搜,所以这样决策无后效性。

    对于按深度排序,可以先 (dfs) 再排,后直接一个 (bfs)

    Code:
    #include<bits/stdc++.h>
    #define ri register signed
    #define p(i) ++i
    using namespace std;
    namespace IO{
        char buf[1<<21],*p1=buf,*p2=buf;
        #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
        template<typename T>inline void read(T &x) {
            ri f=1;x=0;char ch=gc();
            while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
            while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
            x=f?x:-x;
        }
    }
    using IO::read;
    namespace nanfeng{
        #define cmax(x,y) ((x)>(y)?(x):(y))
        #define cmin(x,y) ((x)>(y)?(y):(x))
        #define FI FILE *IN
        #define FO FILE *OUT
        static const int N=1e5+7;
        int que[N],first[N],vis[N],fa[N],dep[N],t=1,n,k,tt,ans;
        struct edge{int v,nxt;}e[N<<1];
        inline void add(int u,int v) {
            e[t].v=v;
            e[t].nxt=first[u];
            first[u]=t++;
        }
        inline void bfs() {
            int hd=1,tl=0,tot=0;
            que[p(tl)]=1;
            while(hd<=tl) {
                int x=que[hd++];
                dep[p(tot)]=x;
                for (ri i(first[x]),v;i;i=e[i].nxt) {
                    if (fa[v=e[i].v]||v==1) continue;
                    fa[que[p(tl)]=e[i].v]=x;   
                }
            }
        }
        void dfs(int x,int fa,int dis){
            vis[x]=1;
            if (dis==k) return;
            for (ri i(first[x]),v;i;i=e[i].nxt) if ((v=e[i].v)!=fa) dfs(v,x,dis+1);
        }
        inline int find(int x) {
            for (ri i(1);i<=k;p(i)) {
                x=fa[x];
                if (!x) return 1; 
            }
            return x;
        }
        inline int main() {
            // FI=freopen("nanfeng.in","r",stdin);
            // FO=freopen("nanfeng.out","w",stdout);
            read(n),read(k),read(tt);
            for (ri i(1);i<n;p(i)) {
                int u,v;read(u),read(v);
                add(u,v);add(v,u);
            }
            bfs();
            for (ri i(n);i;--i) {
                if (vis[dep[i]]) continue;
                p(ans);
                int f=find(dep[i]);
                dfs(f,0,0);
            }
            printf("%d
    ",ans);
            return 0;
        }
    }
    int main() {return nanfeng::main();}
    
  • 相关阅读:
    完美正方形-深度遍历
    CGCDSSQ Codeforces 475D
    [国家集训队]happiness
    点分治学习笔记
    [POI2008]PLA-Postering
    [20200801NOIP提高组模拟T2]电话线铺设
    [20200801NOIP提高组模拟T3]老司机
    [HNOI2001]产品加工
    分层图最短路[学习笔记]
    次芝麻
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/14950638.html
Copyright © 2020-2023  润新知