[bzoj1316]树上的询问_点分治
2024-09-25 20:15:16
树上的询问 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;
}
小结:这种题更适合入门题。
最新文章
- 廖雪峰Python教程疑问
- 烂泥:源码安装apache
- Innodb 表空间卸载、迁移、装载
- Java容器题库
- J2EE学习中一些值得研究的开源项(转)
- PHP 统计中文字符串的长度
- [terry笔记]ArchiveLog归档日志激增解决思路
- 说明一下JNI 与AIDL
- 继电器Relay:ZZR08
- 关于$GLOBALS[&#39;ecs&#39;]->;table()的问题?
- centos 6.6 ios镜像文件 下载 官网和阿里云两种方式教你下载
- ubuntu18.04安装搜狗拼音
- poj-1807(最大流)
- Linux yum源
- delphi ribbon使用
- UVA1714 Keyboarding(bfs)
- Reset GitLab Root Password
- [golang grpc] 框架介绍
- antd-mobile的按需加载
- 常用前端UI框架
热门文章
- hihocoder 1671 反转子串
- PCB决策引擎:多维决策表转决策树
- BZOJ 4808 二分图最大独立集
- fusionchart简单demo柱状图
- 书不在多,精读则灵 - Oracle入门书籍推荐
- VMWare linux 打印太多,看不到之前的记录的解决方法总结
- 扩展银行项目,添加一个(客户类)Customer类。Customer类将包含一个Account对象。
- 【Oracle】数据迁移工具(2):Data Dump
- 使用cookies查询商品详情
- 基于神经网络的混合计算(DNC)-Hybrid computing using a NN with dynamic external memory