zoukankan      html  css  js  c++  java
  • BZOJ4346 : [POI2016]Nadajniki

    设$f[x][j]$表示$x$点不放无线,它的儿子里放了$j$个无线,且对$x$的父亲不作要求时的最小代价。

    $g[x][j]$表示$x$点不放无线,要求$x$的父亲至少放$j$个无线时的最小代价。

    $h[x][j]$表示$x$点放了$j$个无线时的最小代价。

    然后从底向上树形DP即可,时间复杂度$O(n)$。

    #include<cstdio>
    #define rep(i,n) for(int i=0;i<n;i++)
    const int N=200010,M=400010;
    int n,i,x,y,G[N],v[M],nxt[M],ed,f[N][3],g[N][2],h[N][2],old[N][3][3],tmp[3][3],ans;
    inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
    inline int min(int a,int b){return a<b?a:b;}
    inline int max(int a,int b){return a>b?a:b;}
    inline void up(int&a,int b){if(a>b)a=b;}
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=G[x];G[x]=ed;}
    void dfs(int x,int y){
      h[x][0]=1,h[x][1]=2;
      rep(a,3)f[x][a]=M;
      rep(a,3)rep(b,3)old[x][a][b]=M;old[x][0][0]=0;
      for(int i=G[x],u;i;i=nxt[i])if(v[i]!=y){
        dfs(u=v[i],x);
        int t=min(min(h[u][0],h[u][1]),g[u][0]);
        rep(a,3)up(t,f[u][a]);
        h[x][0]+=t;
        h[x][1]+=min(t,g[u][1]);
        rep(a,3)rep(b,3)tmp[a][b]=M;
        rep(a,3)rep(b,3){
          rep(c,3)up(tmp[a][max(b,2-c)],old[x][a][b]+f[u][c]);
          rep(c,2)up(tmp[min(a+c+1,2)][b],old[x][a][b]+h[u][c]);
        }
        rep(a,3)rep(b,3)old[x][a][b]=tmp[a][b];
      }
      rep(a,3)rep(b,a+1)up(f[x][a],old[x][a][b]);
      g[x][0]=min(old[x][0][1],old[x][1][2]);
      g[x][1]=old[x][0][2];
    }
    int main(){
      read(n);
      for(i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
      dfs(1,0);
      ans=min(h[1][0],h[1][1]);
      rep(i,3)up(ans,f[1][i]);
      return printf("%d",ans),0;
    }
    

      

  • 相关阅读:
    【转】c++继承中的内存布局
    Google 开源项目风格指南
    常见面试题
    PHP7.1中使用openssl替换mcrypt
    phpunit实践笔记
    PHP的错误处理
    CI的扩展机制
    #CI的MVC实现
    Laravel中的队列处理
    laravel的模块化是如何实现的
  • 原文地址:https://www.cnblogs.com/clrs97/p/5006919.html
Copyright © 2011-2022 走看看