题目描述

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

输入

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

输出

输出有p行,Yes或No.

样例输入

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

样例输出

Yes
Yes
No
Yes


题解

树的点分治+STL-set

由于有多组询问,所以可以考虑把询问离线,然后一起处理(貌似暴力也能过)。

然后就是点分治的经典题目了。

每次找子树是查询以前的某深度与现在的某深度形成的路径长度是否为l。这个可以使用set维护。

时间复杂度$O(nq\log^2n)=O(能过)$。

#include <set>
#include <cstdio>
#define N 10010
using namespace std;
set<int> s;
int m , a[N] , head[N] , to[N << 1] , len[N << 1] , next[N << 1] , cnt , si[N] , mx[N] , sum , root , deep[N] , vis[N] , d[N] , tot;
bool ans[N];
void add(int x , int y , int z)
{
to[++cnt] = y , len[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
}
void getroot(int x , int fa)
{
int i;
si[x] = 1 , mx[x] = 0;
for(i = head[x] ; i ; i = next[i])
if(!vis[to[i]] && to[i] != fa)
getroot(to[i] , x) , si[x] += si[to[i]] , mx[x] = max(mx[x] , si[to[i]]);
mx[x] = max(mx[x] , sum - si[x]);
if(mx[x] < mx[root]) root = x;
}
void dfs(int x , int fa)
{
int i;
si[x] = 1 , d[++tot] = deep[x];
for(i = head[x] ; i ; i = next[i])
if(!vis[to[i]] && to[i] != fa)
deep[to[i]] = deep[x] + len[i] , dfs(to[i] , x) , si[x] += si[to[i]];
}
void solve(int x)
{
int i , j , k;
vis[x] = 1 , s.clear() , s.insert(0);
for(i = head[x] ; i ; i = next[i])
{
if(!vis[to[i]])
{
tot = 0 , deep[to[i]] = len[i] , dfs(to[i] , 0);
for(j = 1 ; j <= tot ; j ++ )
for(k = 1 ; k <= m ; k ++ )
if(s.find(a[k] - d[j]) != s.end())
ans[k] = 1;
for(j = 1 ; j <= tot ; j ++ ) s.insert(d[j]);
}
}
for(i = head[x] ; i ; i = next[i])
if(!vis[to[i]])
sum = si[to[i]] , root = 0 , getroot(to[i] , 0) , solve(root);
}
int main()
{
int n , i , x , y , z;
scanf("%d%d" , &n , &m);
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" , &a[i]);
if(!a[i]) ans[i] = 1;
}
mx[0] = 1 << 30 , sum = n , getroot(1 , 0) , solve(root);
for(i = 1 ; i <= m ; i ++ ) printf("%s\n" , ans[i] ? "Yes" : "No");
return 0;
}

【bzoj1316】树上的询问 树的点分治+STL-set的更多相关文章

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

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

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

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

  3. 【点分治】bzoj1316 树上的询问

    #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #defin ...

  4. [bzoj1316] 树上的询问

    裸的点分治.. 及时把已经确定的询问清掉就能快不少.时间复杂度O(nlogn*p) #include<cstdio> #include<iostream> #include&l ...

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

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

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

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

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

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

  8. 【bzoj3362/3363/3364/3365】[Usaco2004 Feb]树上问题杂烩 并查集/树的直径/LCA/树的点分治

    题目描述 农夫约翰有N(2≤N≤40000)个农场,标号1到N,M(2≤M≤40000)条的不同的垂直或水平的道路连结着农场,道路的长度不超过1000.这些农场的分布就像下面的地图一样, 图中农场用F ...

  9. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

随机推荐

  1. 【51nod1743】雪之国度(最小生成树+倍增)

    点此看题面 大致题意: 给你一张无向连通图,其中每条边的边权为这条边连接的两点的权值之差.每次询问两点之间是否存在两条不重复的路径,若存在则输出这两条路径上最大值的最小值. 大致思路 这题显然就是要让 ...

  2. 2018.10.05 TOPOI提高组模拟赛 解题报告

    得分: \(100+5+100=205\)(真的是出乎意料) \(T1\):抵制克苏恩(点此看题面) 原题: [BZOJ4832][Lydsy1704月赛] 抵制克苏恩 应该还是一个比较简单的\(DP ...

  3. 第九章 利用DOM脚本检索,替换,设置,追加样式信息

    我们浏览器里看到的网页是由以下三层信息构成的一个共同体: -结构层,由HTML或XHTML之类的标记语言负责去搭建文档的结构. -表示层,由CSS负责设置文档的呈现效果. -行为层,由JavaScri ...

  4. Hotkeys.js 2.0.2 发布,JS 网页快捷键设置,捕获键盘输入和输入的组合键快捷键,它没有依赖

    这是一个强健的 Javascript 库用于捕获键盘输入和输入的组合键,它没有依赖,压缩只有只有(~3kb),gzip:1.9k. 更新内容: 添加测试用例: 添加更多特殊键支持: 修复bug. __ ...

  5. SummerVocation_Learning--java的线程同步

    public class Test_XCTB implements Runnable{ Timer timer = new Timer(); public static void main(Strin ...

  6. BZOJ2287: 【POJ Challenge】消失之物(背包dp)

    题意 ftiasch 有 N 个物品, 体积分别是 W1, W2, ..., WN. 由于她的疏忽, 第 i 个物品丢失了. “要使用剩下的 N - 1 物品装满容积为 x 的背包,有几种方法呢?” ...

  7. oracle一些常用的数据类型

    字符数据类型 char数据类型 当需要固定长度时,使用char数据类型,此数据类型长度可以使1-2000字节.若是不指定大小默认占1字节,如果长度有空余时会以空格进行填充,如果大于设定长度 数据库则会 ...

  8. Python知识点入门笔记——基本控制流程

    复合赋值语句 在Python中,可以使用一次赋值符号,给多个变量同时赋值:                  划重点:age_1,age_2 = age_2,age_1这种操作是Python独有的 i ...

  9. 科学计算库Numpy——数组生成

    等差数组 使用np.arange()或np.linspace()生成元素是等差数列的数组. 以10为底的数组 使用np.logspace()生成元素是以10为底的数组. 数组扩展 使用np.meshg ...

  10. 【104】Maven3.5.0结合eclipse使用,提示Lambda expressions are allowed only at source level 1.8 or above错误的解决方法

    错误重现 我的机器上安装了 maven 3.5.0,在 eclipse 中创建 maven 项目.pom.xml配置如下: <project xmlns="http://maven.a ...