E81 树上背包 CF1830D Mex Tree

视频链接:E81 树上背包 CF1830D Mex Tree_哔哩哔哩_bilibili

 

 

CF1830D Mex Tree - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

// 树上背包 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);
  }
}

 

C++ vector容器的swap方法(容器互换)_vector swap-CSDN博客

C/C++编程:正确释放vector的内存(clear(), swap(), shrink_to_fit())_std::vector clear-CSDN博客

 

posted @ 2024-11-16 16:02  董晓  阅读(35)  评论(0编辑  收藏  举报