• luogu 3806


    https://www.luogu.org/problemnew/show/P3806

    点分治棵题

    对于每次询问,离线处理,每次取重心点分治,查询到每个位置,对于每次询问进行查询.

    #include<stdio.h>
    #include<algorithm>
    #include<set>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    #define ROF(i,s,t) for(register int i=s;i>=t;--i)
    #define VIS(now) for(register int e=las[now];e;e=nxt[e])
    using std::set;
    const int N=10011,MAXX=10000011;
    int heap[N],keep[N];
    bool vis[N],ans[N];
    int n,m,tot,k;
    int nxt[N<<1],las[N],to[N<<1],q[N],sz[N],w[N<<1],dis[N<<1];
    set<int>s;
    int x,y,z;
    inline void add(int x,int y,int z){
        nxt[++tot]=las[x];las[x]=tot;to[tot]=y;w[tot]=z;
    }
    inline void dfs_size(int x,int p,int &mn,int &G){
        sz[x]=1;
        int maxx=0;
        VIS(x)
            if(to[e]!=p&&!vis[to[e]]){
                dfs_size(to[e],x,mn,G);
                sz[x]+=sz[to[e]];
                if(maxx<sz[to[e]])
                    maxx=sz[to[e]];
            }
        if(maxx<n-sz[x])
            maxx=n-sz[x];
        if(maxx<mn)
            mn=maxx,G=x;
    }
    inline int getG(int x){
        int mn=n,G=0;
        dfs_size(x,0,mn,G);
        return G;
    }
    inline void dfs_path(int x,int p,int len){
        if(len>k)return;
        keep[++keep[0]]=len;
        FOR(i,1,m)
            if(s.count(q[i]-len))ans[i]=1;
        VIS(x)
            if(to[e]!=p&&!vis[to[e]])
                dfs_path(to[e],x,len+w[e]);
    }
    inline void find(int x){
        int G=getG(x);
        s.clear();
        s.insert(0); 
        vis[G]=1;
        VIS(G)
            if(!vis[to[e]]){
                keep[0]=0;
                dfs_path(to[e],G,w[e]);
                FOR(i,1,keep[0])
                    s.insert(keep[i]); 
            }
        VIS(G)
            if(!vis[to[e]])
                find(to[e]);
    }
    int main(){
        scanf("%d%d",&n,&m); 
        FOR(i,2,n){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        FOR(i,1,m){
            scanf("%d",q+i); 
            if(q[i]>k)k=q[i];
        }
        find(1);
        FOR(i,1,m)
            ans[i]?puts("AYE"):puts("NAY");
        return 0;
    }
    

      

  • 相关阅读:
    写给自己的话
    软件开发之技能梳理
    《创新者的窘境》读书笔记
    我的四年踩坑史以及思考
    认识问题和求解问题的一种思考框架
    《时间的秩序》读书笔记
    从JSON中自动生成对应的对象模型
    考考你:一道题引发的小思考
    哈!如果一生只如花样短暂
    使用正则表达式抽取所需文本
  • 原文地址:https://www.cnblogs.com/Stump/p/7904413.html
Copyright © 2020-2023  润新知