题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1316

因为只要求存在某条路径长度为K,所以点分,然后用set判断差值是否在set中就可以了。

#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#include<set>
#include<cmath>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define maxn 10900
#define inf int(1e9)
#define mm 1000000007
#define esp 1e-6
using namespace std;
#define ll long long
struct data{int obj,pre; ll c;
}e[maxn*2];
int head[maxn],s[maxn],ans[maxn],q[maxn],vis[maxn];
int n,m,tot,sum,mn,rt;
set<ll> bst;
int read(){
    int x=0,f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
    return x*f;
}
void insert(int x,int y,int z){
    e[++tot].obj=y; e[tot].pre=head[x]; e[tot].c=z; head[x]=tot;
}
void dfs(int u,int fa){
    s[u]=1;  
    int mx=0;
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (!vis[v]&&v!=fa){
            dfs(v,u);
            s[u]+=s[v];
             mx=max(mx,s[v]);
        }
    }
    mx=max(sum-mx,mx);
    if (mx<mn) mn=mx,rt=u;
}
void add(int u,int fa,ll w){
    bst.insert(w);
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (v!=fa&&!vis[v])add(v,u,w+e[j].c);
    }
}
void update(int u,int fa,ll w){
    rep(i,1,m) if (!ans[i])
        ans[i]|=(bst.find(q[i]-w)!=bst.end());
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (v!=fa&&!vis[v]) update(v,u,w+e[j].c);
    }
}
void solve(int u){
    mn=inf;
    dfs(u,0);
    u=rt;
    
    bst.clear(); bst.insert(0);
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (!vis[v]) update(v,u,e[j].c),add(v,u,e[j].c);     //先判断点再加边。
    }
    
    vis[u]=1;
    for (int j=head[u];j;j=e[j].pre){
        int v=e[j].obj;
        if (!vis[v]){
            sum=s[v];
            solve(v);
        }
    }
    
}
int main(){
    n=read(); m=read();
    int x,y,z;
    rep(i,1,n-1){
        x=read(); y=read(); z=read();
        insert(x,y,z);
        insert(y,x,z);
    }
    rep(i,1,m) q[i]=read();
    sum=n;

solve(1);
    rep(i,1,m) if(!q[i]) ans[i]=1;   //如果q[i]=0,那么可以只选取一个点。
    rep(i,1,m) if (ans[i]) puts("Yes"); else puts("No");
    return 0;
}

BZOJ 1316: 树上的询问 (点分治+set)的更多相关文章

  1. BZOJ 1316: 树上的询问( 点分治 + 平衡树 )

    直接点分治, 用平衡树(set就行了...)维护. -------------------------------------------------------------------------- ...

  2. BZOJ 1316: 树上的询问

    挺裸的点分治 刚开始想用map水过去,然后做p次点分治,然后T到自闭 最后发现可以sort一遍,然后去重,记录每个数出现的次数,这样就可以双指针,不会漏掉了 #include <bits/std ...

  3. [BZOJ1316]树上的询问 点分治

    1316: 树上的询问 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1017  Solved: 287[Submit][Status][Discus ...

  4. 【BZOJ1316】树上的询问 点分治+set

    [BZOJ1316]树上的询问 Description 一棵n个点的带权有根树,有p个询问,每次询问树中是否存在一条长度为Len的路径,如果是,输出Yes否输出No. Input 第一行两个整数n, ...

  5. BZOJ.3784.树上的路径(点分治 贪心 堆)

    BZOJ \(Description\) 给定一棵\(n\)个点的带权树,求树上\(\frac{n\times(n-1)}{2}\)条路径中,长度最大的\(m\)条路径的长度. \(n\leq5000 ...

  6. [POJ 1316] 树上的询问

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1316 [算法] 点分治 由于边权较大,笔者在计算时使用了STL-set 注意当询问为 ...

  7. BZOJ 3784: 树上的路径 点分治+二分+set

    很容易想出二分这个思路,但是要想办法去掉一个 $log$. 没错,空间换时间. 双指针的部分错了好几次~ Code: #include <set> #include <queue&g ...

  8. BZOJ_1316_树上的询问_点分治

    BZOJ_1316_树上的询问_点分治 Description 一棵n个点的带权有根树,有p个询问,每次询问树中是否存在一条长度为Len的路径,如果是,输出Yes否输出No. Input 第一行两个整 ...

  9. [bzoj1316]树上的询问_点分治

    树上的询问 bzoj-1316 题目大意:一棵n个点的带权有根树,有p个询问,每次询问树中是否存在一条长度为Len的路径,如果是,输出Yes否输出No. 注释:$1\le n\le 10^4$,$1\ ...

随机推荐

  1. iOS 多线程 简单学习NSThread NSOperation GCD

    1:首先简单介绍什么叫线程 可并发执行的,拥有最小系统资源,共享进程资源的基本调度单位. 共用堆,自有栈(官方资料说明iOS主线程栈大小为1M,其它线程为512K). 并发执行进度不可控,对非原子操作 ...

  2. n年前,我没钱但年轻,我怕n年后我老时,还是一无所成——2017我的收获和反思

    记得当年我刚从学校里出来时,应该和现在的95后差不多,当时还是很惶恐的,怕找不到工作,怕无法挣到足够的钱买房子支撑家庭,(当然还有其它的担心点),却唯独没意识到自己拥有着最宝贵的财富:年轻. 年轻意味 ...

  3. bzoj 1597: [Usaco2008 Mar]土地购买

    Description 农 夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <= 1,000 ...

  4. g4e基础篇#1 什么是版本控制系统

    g4e 是 Git for Enterprise Developer的简写,这个系列文章会统一使用g4e作为标识,便于大家查看和搜索. 章节目录 前言 1. 基础篇: 为什么要使用版本控制系统 Git ...

  5. js随机数生成,生成m-n的随机数

    使用js生成n到m间的随机数字,主要目的是为后期的js生成验证码做准备,Math.random()函数返回0和1之间的伪随机数 var random = Math.random(); console. ...

  6. Android 7.1 WindowManagerService 屏幕旋转流程分析 (三)

    三.屏幕的绘制 performSurfacePlacement()函数来触发window的绘制,这里最大的循环次数是6,当然一般不会到最大次数就会被Scheduled. final void perf ...

  7. C语言学生管理系统(原版本)(自编)

    /*系统特色:(大牛勿笑) *颜色提示 *文字提示 *功能 */ #include <stdio.h> #include <stdlib.h> #include <mat ...

  8. php中const与define的区别

    1 版本差异: const 要求php的版本>5.3.0 define 可以兼容php4,php5 等版本 2 定义的位置区别: const关键字定义的常量是在编译时定义的,因此const关键字 ...

  9. 微信小程序开发之普通链接二维码

    本文主要介绍扫普通链接二维码打开小程序, 详情请看官方文档https://mp.weixin.qq.com/debug/wxadoc/introduction/qrcode.html 配置普通链接二维 ...

  10. 微信小程序开发之详解生命周期方法

    生命周期是指一个小程序从创建到销毁的一系列过程 在小程序中 ,通过App()来注册一个小程序 ,通过Page()来注册一个页面 先来看一张小程序项目结构 从上图可以看出,根目录下面有包含了app.js ...