zoukankan      html  css  js  c++  java
  • BZOJ_1316_树上的询问_点分治

    BZOJ_1316_树上的询问_点分治

    Description

    一棵n个点的带权有根树,有p个询问,每次询问树中是否存在一条长度为Len的路径,如果是,输出Yes否输出No.

    Input

    第一行两个整数n, p分别表示点的个数和询问的个数. 接下来n-1行每行三个数x, y, c,表示有一条树边x→y,长度为c. 接下来p行每行一个数Len,表示询问树中是否存在一条长度为Len的路径.

    Output

    输出有p行,Yes或No.

    Sample Input

    6 4
    1 2 5
    1 3 7
    1 4 1
    3 5 2
    3 6 3
    1
    8
    13
    14

    Sample Output

    Yes
    Yes
    No
    Yes


    HINT

    30%的数据,n≤100.
    100%的数据,n≤10000,p≤100,长度≤1000000.

    做完此题可看下POJ 3237 Tree


    和Race那道题差不多,由于p很小可以暴力统计。

    时间复杂度O(p*n*logn)

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 10050
    #define maxl 1000000
    int head[N],to[N<<1],nxt[N<<1],val[N<<1],cnt,n,m;
    int fag[N],siz[N],ask[150],tot,solved[150],a[N],b[N],dis[N],root;
    bool used[N],buc[1000010][2];
    inline void add(int u,int v,int w) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w; 
    }
    void getroot(int x,int y) {
        fag[x]=0; siz[x]=1;
        int i;
        for(i=head[x];i;i=nxt[i]) {
            if(to[i]!=y&&!used[to[i]]) {
                getroot(to[i],x);
                siz[x]+=siz[to[i]];
                fag[x]=max(fag[x],siz[to[i]]);
            }
        }
        fag[x]=max(fag[x],tot-siz[x]);
        if(fag[root]>fag[x]) {root=x;}
    }
    void getdep(int x,int y) {
        int i;
        if(dis[x]<=maxl){
            a[++a[0]]=dis[x];
            b[++b[0]]=dis[x];
        }
        siz[x]=1;
        for(i=head[x];i;i=nxt[i]) {
            if(to[i]!=y&&!used[to[i]]) {
                dis[to[i]]=dis[x]+val[i];
                getdep(to[i],x);
                siz[x]+=siz[to[i]]; 
            }
        }
    }
    void getsiz(int x,int y) {
        int i;
        siz[x]=1;
        for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&!used[to[i]]) {
            getsiz(to[i],x);
            siz[x]+=siz[to[i]];
        }
    }
    void work(int x) {
        used[x]=1;
        int i,j,k;
        dis[x]=0;
        b[0]=0;
        b[++b[0]]=0;
        for(i=head[x];i;i=nxt[i]) if(!used[to[i]]) {
            a[0]=0;
            a[++a[0]]=0;
            dis[to[i]]=val[i];
            getdep(to[i],0);
            for(k=1;k<=m;k++) if(!solved[k]) {
                for(j=1;j<=a[0];j++) {
                    if(a[j]<=ask[k]&&buc[ask[k]-a[j]][0])
                        solved[k]=1;  
                }
            }
            for(j=1;j<=a[0];j++) buc[a[j]][0]=1,buc[a[j]][1]=0;
        }
        for(i=1;i<=b[0];i++) {
            buc[b[i]][0]=buc[b[i]][1]=0;
        }
        getsiz(x,0);
        for(i=head[x];i;i=nxt[i]) if(!used[to[i]]) {
            tot=siz[to[i]];
            root=0;
            getroot(to[i],0);
            work(root); 
        }
    }
    int main() {
        scanf("%d%d",&n,&m);
        int i,x,y,z;
        for(i=1;i<n;i++) {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z); add(y,x,z);
        }
        for(i=1;i<=m;i++) {
            scanf("%d",&ask[i]);
            if(!ask[i]) solved[i]=1;    
        }
        fag[0]=100000000;
        tot=n;
        getroot(1,0);
        work(root);
        for(i=1;i<=m;i++) {
            if(solved[i]) puts("Yes");
            else puts("No");    
        }
    }
    
  • 相关阅读:
    2019阿里系电子书合集来了!
    FTP主动模式和被动模式的区别
    Vsftpd运行的两种模式-xinetd运行模式和 standalone模式
    Logstash组件详解(input、codec、filter、output)
    Docker入门-笔记-1
    K8S命令-Kubectl 命令大全
    Nginx-HTTP Strict Transport Security(HSTS)
    IPV6技术笔记(剖析IPv4toIPv6)
    一个交换机到底能带几台摄像头?结合生产经验咱们来分析!
    ELK查询命令详解
  • 原文地址:https://www.cnblogs.com/suika/p/8831610.html
Copyright © 2011-2022 走看看