树上的询问 bzoj-1316

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

注释:$1\le n\le 10^4$,$1\le p\le 100$,长度$\le 10^6$。

想法:有根树tm是啥意思?根在jb哪呢?老子我瞅tm这么半天也没看见根在哪呢??这题点分治即可。我们用点分治的第二种:分别计算子树,然后用之前的信息更新答案。对于此题,我们可以直接维护一个set就行。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#define N 10010
using namespace std;
set<int>s;
int n,m,sum,root,cnt;
int a[N],dic[N<<1],size[N],mx[N],deep[N];
bool vis[N],ans[N];
int to[N<<1],head[N],val[N<<1],nxt[N<<1],tot;
inline void add(int x,int y,int z)
{
to[++tot]=y;
val[tot]=z;
nxt[tot]=head[x];
head[x]=tot;
}
void getroot(int pos,int fa)
{
mx[pos]=0,size[pos]=1;
for(int i=head[pos];i;i=nxt[i])
{
if(to[i]==fa||vis[to[i]]) continue;
getroot(to[i],pos);
size[pos]+=size[to[i]];
mx[pos]=max(mx[pos],size[to[i]]);
}
mx[pos]=max(mx[pos],sum-size[pos]);
if(mx[root]>mx[pos]) root=pos;
}
void getdeep(int pos,int fa)
{
size[pos]=1;
dic[++cnt]=deep[pos];
for(int i=head[pos];i;i=nxt[i])
{
if(to[i]==fa||vis[to[i]]) continue;
deep[to[i]]=deep[pos]+val[i];
getdeep(to[i],pos);
size[pos]+=size[to[i]];
}
}
void dispose(int pos)
{
// cout << " Fuck && Shit " << endl ;
vis[pos]=true;
s.clear();
s.insert(0);
for(int i=head[pos];i;i=nxt[i])
{
// cout << " Fuck 2" << endl ;
if(vis[to[i]]) continue;
cnt=0; deep[to[i]]=val[i],getdeep(to[i],0);
for(int j=1;j<=cnt;j++)
{
for(int k=1;k<=m;k++)
{
if(s.find(a[k]-dic[j])!=s.end()) ans[k]=1;
}
}
for(int j=1;j<=cnt;j++) s.insert(dic[j]);
}
for(int i=head[pos];i;i=nxt[i])
{
if(vis[to[i]]) continue;
sum=size[to[i]];
root=0;
getroot(to[i],0);
dispose(root);
// cout << " Fuck " << endl ;
}
}
int main()
{
scanf("%d%d",&n,&m);
int x,y,c;
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&c);
add(x,y,c),add(y,x,c);
}
// cout << "Fuck1" << endl ;
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
if(!a[i]) ans[i]=1;
}
mx[0]=1<<30;
sum=n;
// cout << "Fuck1" << endl ;
getroot(1,0);
// cout << "Fuck1" << endl ;
dispose(root);
// cout << "Fuck : " << m << endl ;
for(int i=1;i<=m;i++)
{
printf("%s\n",ans[i]?"Yes":"No");
}
return 0;
}

小结:这种题更适合入门题。

最新文章

  1. 廖雪峰Python教程疑问
  2. 烂泥:源码安装apache
  3. Innodb 表空间卸载、迁移、装载
  4. Java容器题库
  5. J2EE学习中一些值得研究的开源项(转)
  6. PHP 统计中文字符串的长度
  7. [terry笔记]ArchiveLog归档日志激增解决思路
  8. 说明一下JNI 与AIDL
  9. 继电器Relay:ZZR08
  10. 关于$GLOBALS[&#39;ecs&#39;]-&gt;table()的问题?
  11. centos 6.6 ios镜像文件 下载 官网和阿里云两种方式教你下载
  12. ubuntu18.04安装搜狗拼音
  13. poj-1807(最大流)
  14. Linux yum源
  15. delphi ribbon使用
  16. UVA1714 Keyboarding(bfs)
  17. Reset GitLab Root Password
  18. [golang grpc] 框架介绍
  19. antd-mobile的按需加载
  20. 常用前端UI框架

热门文章

  1. hihocoder 1671 反转子串
  2. PCB决策引擎:多维决策表转决策树
  3. BZOJ 4808 二分图最大独立集
  4. fusionchart简单demo柱状图
  5. 书不在多,精读则灵 - Oracle入门书籍推荐
  6. VMWare linux 打印太多,看不到之前的记录的解决方法总结
  7. 扩展银行项目,添加一个(客户类)Customer类。Customer类将包含一个Account对象。
  8. 【Oracle】数据迁移工具(2):Data Dump
  9. 使用cookies查询商品详情
  10. 基于神经网络的混合计算(DNC)-Hybrid computing using a NN with dynamic external memory