zoukankan      html  css  js  c++  java
  • BZOJ4042 : [Cerc2014] parades

    设f[x]为x子树里能选的最多的路径数,h[x]为x子树里往上走的点的集合,且不与x子树内的最优解冲突

    首先f[x]=sum(f[son])

    若h[son]与x可以直接匹配,则匹配上,f[x]++

    然后把剩下的未配对的son之间进行匹配,f[x]+=最大匹配数

    因为度数不超过10,所以设dp[S]表示二进制表示为S的集合里的最大匹配,x=lowbit(S),则

    dp[S]=max(dp[S^(1<<x)],dp[S^(1<<x)^(1<<y)]+1),其中y属于S,y>x,且x与y可以匹配

    若dp[(1<<t)-1]==dp[((1<<t)-1)^(1<<i)],则表明i不在最优解中,需要将其加入h[x]中

    时间复杂度$O(n2^{10})$。

    #include<cstdio>
    const int N=1010,K=10;
    int T,n,m,i,x,y,f[N],q[K],t,a[K][K],dp[1<<K];bool e[N][N];
    struct E{int v;E*nxt;}*g[N],*h[N],pool[1010000],*cur=pool;
    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 void addg(int x,int y){E*p=cur++;p->v=y;p->nxt=g[x];g[x]=p;}
    inline void addh(int x,int y){E*p=cur++;p->v=y;p->nxt=h[x];h[x]=p;}
    inline bool match(int x,int y){
      for(E*i=h[x];i;i=i->nxt)for(E*j=h[y];j;j=j->nxt)if(e[i->v][j->v])return 1;
      return 0;
    }
    inline void up(int&a,int b){if(a<b)a=b;}
    void dfs(int x,int y){
      f[x]=0,h[x]=NULL;
      for(E*i=g[x];i;i=i->nxt)if(i->v!=y)dfs(i->v,x),f[x]+=f[i->v];
      t=0;
      for(E*i=g[x];i;i=i->nxt)if(i->v!=y){
        bool flag=1;
        for(E*j=h[i->v];j;j=j->nxt)if(e[x][j->v]){f[x]++,flag=0;break;}
        if(flag)q[t++]=i->v;
      }
      for(int i=0;i<t;i++)for(int j=i+1;j<t;j++)a[i][j]=match(q[i],q[j]);
      int F=(1<<t)-1;
      for(int S=1;S<=F;S++){
        int i=__builtin_ctz(S&-S);
        dp[S]=dp[S^(1<<i)];
        for(int U=S-(S&-S);U;U-=U&-U){
          int j=__builtin_ctz(U&-U);
          if(a[i][j])up(dp[S],dp[S^(1<<i)^(1<<j)]+1);
        }
      }
      f[x]+=dp[F],addh(x,x);
      for(int i=0;i<t;i++)if(dp[F]==dp[F^(1<<i)])for(E*j=h[q[i]];j;j=j->nxt)addh(x,j->v);
    }
    int main(){
      for(read(T);T--;printf("%d
    ",f[1])){
        for(read(n),i=1;i<n;i++)read(x),read(y),addg(x,y),addg(y,x);
        for(read(m);m--;e[x][y]=e[y][x]=1)read(x),read(y);
        dfs(1,0);
        for(cur=pool,i=1;i<=n;i++)for(g[i]=NULL,x=1;x<=n;x++)e[i][x]=0;
      }
      return 0;
    }
    

      

  • 相关阅读:
    [转载]Python量化交易平台开发教程系列1-类CTP交易API的工作原理
    [转载]Python量化交易平台开发教程系列0-引言
    Wind量化平台使用点评
    掘金量化使用点评
    Tushare使用点评
    量化交易的Python工具链
    可见光通信与室内定位技术
    Qt5下实现摄像头预览及捕获图像方法二(openCV3与Qt5交互使用)
    ubuntu下软件包安装故障解决方案(深入剖析专治疑难)
    Qt5下实现摄像头预览及捕获图像方法一
  • 原文地址:https://www.cnblogs.com/clrs97/p/4703222.html
Copyright © 2011-2022 走看看