• [POJ 1316] 树上的询问


    [题目链接]

            https://www.lydsy.com/JudgeOnline/problem.php?id=1316

    [算法]

              点分治 

              由于边权较大,笔者在计算时使用了STL-set

              注意当询问为0时,要输出"Yes"

    [代码]

          

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 10010
    #define MAXQ 110
    
    struct Edge
    {
        int to,w,nxt;
    } e[MAXN<<1];
    
    int i,n,q,tot,root,u,v,w,len;
    int size[MAXN],head[MAXN],weight[MAXN],sum[MAXN],val[MAXN],a[MAXQ];
    bool visited[MAXN],ans[MAXQ];
    
    inline void addedge(int u,int v,int w)
    {
        tot++;
        e[tot] = (Edge){v,w,head[u]};
        head[u] = tot;
    }
    inline void getroot(int u,int fa,int total)
    {
        int i,v;
        size[u] = 1;
        weight[u] = 0;
        for (i = head[u]; i; i = e[i].nxt)
        {
            v = e[i].to;
            if (fa != v && !visited[v])
            {
                getroot(v,u,total);
                size[u] += size[v];
                weight[u] = max(weight[u],size[v]);
            }
        }
        weight[u] = max(weight[u],total - size[u]);
        if (weight[u] < weight[root]) root = u;
    }
    inline void dfs(int u,int fa)
    {
        int i,v,w;
        val[++len] = sum[u]; 
        for (i = head[u]; i; i = e[i].nxt)
        {
            v = e[i].to;
            w = e[i].w;
            if (v != fa && !visited[v]) 
            {
                sum[v] = sum[u] + w;
                dfs(v,u); 
            }
        }
    }
    inline void calc(int u)
    {
        int i,j,k,v,w;
        set< int > s;
        s.clear();
        s.insert(0);
        for (i = head[u]; i; i = e[i].nxt)
        {
            v = e[i].to;
            w = e[i].w;
            if (!visited[v])
            {
                sum[v] = w;
                len = 0;
                dfs(v,u);
                for (j = 1; j <= len; j++)
                {
                    for (k = 1; k <= q; k++)
                    {
                        if (s.find(a[k] - val[j]) != s.end())
                            ans[k] = true;
                    }
                }
                for (j = 1; j <= len; j++) s.insert(val[j]);
            }
        }
    }
    inline void work(int u)
    {
        int i,v;
        visited[u] = true;
        calc(u);    
        for (i = head[u]; i; i = e[i].nxt)
        {
            v = e[i].to;
            if (!visited[v])
            {
                root = 0;
                getroot(v,0,size[v]);
                work(root);
            }
        }
    }
    
    int main()
    {
        
        
        scanf("%d%d",&n,&q);
        for (i = 1; i < n; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);        
        }
        for (i = 1; i <= q; i++) scanf("%d",&a[i]);
        root = 0;
        size[0] = weight[0] = n;
        getroot(1,0,n);
        work(root);
        for (i = 1; i <= q; i++) printf((ans[i] || a[i] == 0) ? "Yes
    " : "No
    ");
    
        return 0;
    }
  • 相关阅读:
    中文分词技术
    布隆过滤器(Bloom Filter)详解
    真正理解Mysql的四种隔离级别
    从内核文件系统看文件读写过程
    如何评价腾讯开源的消息中间件TubeMQ?
    零拷贝(Zero-copy)及其应用详解
    深入了解RabbitMQ
    (四)下载利器aria2
    (三)轻量级文件服务器filebrowser
    log4j 2整理
  • 原文地址:https://www.cnblogs.com/evenbao/p/9328402.html
Copyright © 2020-2023  润新知