HDU6268 Master of Subgraph(点分治)

看上去比较像点分治的裸题,因此也考虑通过根节点的子图和不通过根节点的子图。

我们要维护的是,如何做到做完一个儿子后,另一个儿子可以使用前面的信息,这里可以使用bitset,题目只给了3000个点其实也提示了这一点

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
const int mod=1e7+7;
int n,idx;
int h[N],ne[N],e[N],w[N];
int cnt[N],vis[N],d[N],sz[N];
int dis[N];
int st[N];
int root;
int m;
bitset<100010> bit[3030],ans;
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs_root(int u,int fa,int tot){
    int i;
    sz[u]=1;
    int ans=0;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa||vis[j])
            continue;
        dfs_root(j,u,tot);
        sz[u]+=sz[j];
        ans=max(ans,sz[j]);
    }
    ans=max(ans,tot-sz[u]);
    if(ans*2<=tot){
        root=u;
    }
}
void dfs_sz(int u,int fa){
    sz[u]=1;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa||vis[j])
            continue;
        dfs_sz(j,u);
        sz[u]+=sz[j];
    }
}
void get(int u,int fa){
    bit[u]<<=w[u];
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa||vis[j])
            continue;
        bit[j]=bit[u];
        get(j,u);
        bit[u]|=bit[j];
    }
}
void work(int u,int tot){
    dfs_root(u,-1,tot);
    u=root;
    vis[u]=1;
    dfs_sz(u,-1);
    bit[u].reset();
    bit[u].set(0);
    get(u,-1);
    ans|=bit[u];
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(vis[j])
            continue;
        work(j,sz[j]);
    }
}
int main(){
    //ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        scanf("%d%d",&n,&m);
        int i;
        ans.reset();
        idx=0;
        for(i=0;i<=n;i++){
             h[i]=-1;
             vis[i]=0;
        }
        for(i=1;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        for(i=1;i<=n;i++)
            scanf("%d",&w[i]);
        work(1,n);
        for(i=1;i<=m;i++){
            printf("%d",(int)ans[i]);
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2020-09-23 20:56  朝暮不思  阅读(179)  评论(0编辑  收藏  举报