zoukankan      html  css  js  c++  java
  • bzoj 3420: Poi2013 Triumphal arch 树形dp+二分

    给一颗树,$1$ 号节点已经被染黑,其余是白的,两个人轮流操作,一开始 $B$ 在 $1$ 号节点,$A$ 选择 $k$ 个点染黑,然后 $B$ 走一步,如果 $B$ 能走到 $A$ 没染的节点则 $B$ 胜,否则当 $A$ 染完全部的点时,$A$ 胜。求能让 $A$ 获胜的最小的 $k$

    我们发现这个 $k$ 是满足单调性的:即如果 $k$ 是一个合法的解,那么 $k+1$ 也一定合法,所以考虑二分 $k$

    现在,我们考虑如果得到一个 $mid$,如何验证 $mid$ 是否合法呢 $?$

    这个状态的设计不太好想:$f[i]$ 表示当 $B$ 到达 $i$ 节点且 $B$ 为后手时 $i$ 的子树中需要被染成黑色的最小数量(不考虑 $i$ 的染色情况).

    如果 $f[1]$ 小于等于 $k$ 的话,则合法.

    考虑如何转移:

    对于 $i$ 的所有子树来说,答案是 $sum_{vin son[i]}f[v]+1$

    因为我们并不考虑一个节点自身的染色情况,所以所有儿子也必须都被提前染上色.

    而由于 $B$ 是后手,$A$ 是先手,所以 $A$ 可以提前将 $k$ 个点先染完,所以:

    $f[i]=max(0,sum_{vin son[i]}(f[v]+1)-k)$

    每一次二分出一个 $k$ 就这么转移一下就好了.

    #include <bits/stdc++.h>      
    #define N 300005   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;  
    int n,edges,k;        
    int hd[N],to[N<<1],nex[N<<1],f[N];        
    void add(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
    }
    void dfs(int u,int ff) 
    {
        int tot=0;      
        f[u]=-k;            
        for(int i=hd[u];i;i=nex[i]) 
        {
            int v=to[i]; 
            if(v==ff) continue;   
            dfs(v,u);   
            f[u]+=f[v]+1;   
        }   
        // printf("%d %d
    ",u,f[u]);    
        f[u]=max(f[u], 0);   
    }
    int main() 
    { 
        // setIO("input"); 
        int i,j; 
        scanf("%d",&n);  
        for(i=1;i<n;++i) 
        {
            int u,v; 
            scanf("%d%d",&u,&v),add(u,v),add(v,u);   
        }
        int l=0,r=n,ans=n;   
        while(l<=r) 
        {
            int mid=(l+r)>>1;     
            for(i=1;i<=n;++i)  f[i]=0;   
            k=mid, dfs(1,0);    
            if(f[1]==0)   ans=mid, r=mid-1;  
            else    l=mid+1; 
        }
        printf("%d
    ",ans);    
        return 0;   
    }
    

      

  • 相关阅读:
    Thread Based Parallelism
    Thread Based Parallelism
    The Divide and Conquer Approach
    Algorithms
    FTP
    POP and IMAP
    通过 python 处理 email
    Android开发环境搭建简介
    Hello world
    mybatis3.2初学感悟
  • 原文地址:https://www.cnblogs.com/guangheli/p/11768956.html
Copyright © 2011-2022 走看看