zoukankan      html  css  js  c++  java
  • 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("
    ");
        }
        return 0;
    }
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    微信企业号开发:UserAgent
    用sinopia搭建内部npm服务
    python format用法详解
    python正则表达式re之compile函数解析
    Socket通信原理
    TCP半开连接与半闭连接
    使用npm安装一些包失败了的看过来(npm国内镜像介绍)
    UI优秀框架(库)
    关于 WebView 知识点的详解
    CommonJS规范
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13721013.html
Copyright © 2011-2022 走看看