1 条题解

  • 0
    @ 2025-11-12 15:05:45

    E81 树上背包 CF1830D Mex Tree

    // 树上背包 O(n*sqrt(n))
    #include<bits/stdc++.h>
    using namespace std;
    
    int read(){
      int d=0;char ch=getchar();
      while(!isdigit(ch))ch=getchar();
      while(isdigit(ch)){d=d*10+ch-48;ch=getchar();}
      return d;
    }
    const int N=200005,INF=0x3f3f3f3f;
    
    int n,sz[N],B,Bu,Bv,T;
    vector<int>e[N],f[N][2];
    
    void dfs(int u,int fa){
      sz[u]=1; vector<int>g[2];
      f[u][0].resize(2); f[u][0][1]=1;
      f[u][1].resize(2); f[u][1][1]=2;
      for(auto v:e[u]){
        if(v==fa) continue;
        dfs(v,u);
        B=ceil(sqrt(sz[u]+sz[v]));
        Bu=ceil(sqrt(sz[u])); Bv=ceil(sqrt(sz[v]));
        g[0].resize(B+2); for(auto &i:g[0]) i=INF;
        g[1].resize(B+2); for(auto &i:g[1]) i=INF;
        for(int i=Bu;i>=1;i--){
          for(int j=Bv;j>=1;j--){
            if(i+j>B) continue;
            g[0][i+j]=min(g[0][i+j],f[u][0][i]+f[v][0][j]+i*j);
            g[1][i+j]=min(g[1][i+j],f[u][1][i]+f[v][1][j]+2*i*j);
            g[0][i]=min(g[0][i],f[u][0][i]+f[v][1][j]);
            g[1][i]=min(g[1][i],f[u][1][i]+f[v][0][j]);
          }
        }
        f[u][0]=g[0]; f[u][1]=g[1];
        vector<int>().swap(f[v][0]);
        vector<int>().swap(f[v][1]); //释放内存空间
        sz[u]+=sz[v];
      }
    }
    
    signed main(){
      T=read();
      while(T--){
        n=read();
        for(int i=1;i<=n;i++) e[i].clear();
        for(int i=1,u,v;i<n;i++){
          u=read();v=read();
          e[u].push_back(v);
          e[v].push_back(u);
        }
        dfs(1,0);
        int ans=INF;
        for(auto i:f[1][0]) ans=min(ans,i);
        for(auto i:f[1][1]) ans=min(ans,i);
        printf("%lld\n",1ll*n*(n+1)-ans);
      }
      return 0;
    }
    

    • 1

    信息

    ID
    1442
    时间
    3000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    145
    已通过
    2
    上传者