其他分享
首页 > 其他分享> > P3806 【模板】点分治1

P3806 【模板】点分治1

作者:互联网

模板*0x3f3f3f3f

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=500005;
const int inf=0x3f3f3f3f;

int n,m,a,b,c,ask[maxn];
bool have[maxn*20],can[maxn],vis[maxn];
vector<int> g[maxn],v[maxn];
int sum,sz[maxn],son[maxn],rt;
int rem[maxn],dis[maxn];
queue<int> q;

void getrt(int x,int f){
    sz[x]=1,son[x]=0;
    for(int i=0;i<g[x].size();++i){
        int y=g[x][i];
        if(vis[y]||y==f) continue;
        getrt(y,x);
        sz[x]+=sz[y];
        son[x]=max(son[x],sz[y]);
    }
    son[x]=max(son[x],sum-sz[x]);
    if(son[x]<son[rt]) rt=x;
}

void getdis(int x,int f){
    rem[++rem[0]]=dis[x];
    for(int i=0;i<g[x].size();++i){
        int y=g[x][i];
        if(vis[y]||y==f) continue;
        dis[y]=dis[x]+v[x][i];
        getdis(y,x);
    }
}

void cal(int x){
    dis[x]=0;
    for(int i=0;i<g[x].size();++i){
        int y=g[x][i];
        if(vis[y]) continue;
        rem[0]=0;//clear the rem every time
        dis[y]=v[x][i];
        getdis(y,x);
        for(int i=rem[0];i;--i){
            for(int j=1;j<=m;++j){
                if(can[j]) continue;
                if(ask[j]>=rem[i])
                    can[j]|=have[ask[j]-rem[i]];
            }
        }
        for(int i=rem[0];i;--i){
            have[rem[i]]=1;
            q.push(rem[i]);
        }
    }
    while(!q.empty()){
        int f=q.front();
        have[f]=0;
        q.pop();
    }
}

void div(int x){
    vis[x]=1,have[0]=1;
    cal(x);
    for(int i=0;i<g[x].size();++i){
        int y=g[x][i];
        if(vis[y]) continue;
        sum=sz[y];
        rt=0;
        son[rt]=inf;
        getrt(y,0);
        div(rt);
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n-1;++i){
        scanf("%d%d%d",&a,&b,&c);
        g[a].push_back(b);
        g[b].push_back(a);
        v[a].push_back(c);
        v[b].push_back(c);
    }
    for(int i=1;i<=m;++i) scanf("%d",&ask[i]);
    sum=n;
    rt=0;
    son[rt]=inf;
    getrt(1,0);
    div(rt);
    for(int i=1;i<=m;++i){
        if(can[i]) puts("AYE");
        else puts("NAY");
    }
    return 0;
}

 

标签:int,分治,son,vis,maxn,rem,P3806,0x3f3f3f3f,模板
来源: https://www.cnblogs.com/oneman233/p/11550948.html