由题开始==

例题:求在一棵有权树上,是否存在一条路径满足权值和为K

解法:以每个点为根一次,看在他的子树间是否存在两段,其和为K;O(==)

和例题一样,对于树上问题,求某些要求的路径(数量或者存在性等),

往往可以先对一条经过根节点的路径操作,

后再删去这个根,对他的子树们同样的操作

显然是一个分治过程

原理就是,一条路径,要么是由一个点经过根节点,与其他子树内的节点形成;

要么就是只在这棵子树内形成路径

大概图示意思(红绿为两条上述路径)



<

当我们的树比较平衡时,每个点被路径计算是$ logn $ 的,但是当树是一条链的时候,就退化成$ n^2 $ 了

为了避免这种情况,可以用树的重心代替,成为新的根。此时总复杂度为$ O (nlogn) 。$

原因就是,一棵树,怎么为根都还是一颗树,但是以重心为根的时候,这颗树是最好看的最平衡的

rt,将链按箭头提起来:





这看向去更像是一棵树

所以

总结一下

一棵树先确定他的重心,以重心为根,确定经过根节点的路径;再把根节点删掉,对于删掉他的子树们,按上述同样操作;

已证$ O(nlogn) $。

luogu模板题代码仅供参考,不解释。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+50;
const int K = 1e7+50;
int n,m;
struct node{int next,to,dis;}edge[N<<1];
int head[N],cnt;
inline void add(int from,int to,int dis) {
edge[++cnt].to=to,edge[cnt].dis=dis,edge[cnt].next=head[from],head[from]=cnt;
}
int q[N],ans[N],maxp[N],size[N],visited[N],tmp[N],dis[N],judge[K];
int rt,sum,tot;
void getrt(int u,int f) {
size[u]=1,maxp[u]=0;
for(int i=head[u];i;i=edge[i].next) {
int v=edge[i].to;if(v==f||visited[v]) continue;
getrt(v,u);
size[u]+=size[v];maxp[u]=max(maxp[u],size[v]);
}
maxp[u]=max(maxp[u],sum-maxp[u]);
if(maxp[u]<maxp[rt]) rt=u;//要求最大的最小
}
void getdis(int u,int f) {
tmp[++tot]=dis[u];
for(int i=head[u];i;i=edge[i].next) {
int v=edge[i].to;if(v==f||visited[v]) continue;
dis[v]=dis[u]+edge[i].dis; getdis(v,u);
}
}
queue<int> que;
void solve(int u) {
for(int i=head[u];i;i=edge[i].next) {
int v=edge[i].to;if(visited[v]) continue;
dis[v]=edge[i].dis;
tot=0;getdis(v,u);
for(int j=1;j<=tot;j++)
for(int k=1;k<=m;k++)
if(q[k]>=tmp[j])
ans[k]|=judge[q[k]-tmp[j]];
for(int j=1;j<=tot;j++) que.push(tmp[j]),judge[tmp[j]]=1;
}
while(!que.empty()) judge[que.front()]=0,que.pop();//数组过大,memset超时
}
void divide(int u) {
judge[0]=visited[u]=1;solve(u);
for(int i=head[u];i;i=edge[i].next) {
int v=edge[i].to;if(visited[v]) continue;
maxp[rt=0]=sum=size[v];
getrt(v,0),getrt(rt,0);
divide(rt);
}
}
int main() {
cin>>n>>m;
for(int i=1;i<n;i++) { int a,b,c;scanf("%d%d%d",&a,&b,&c);add(a,b,c),add(b,a,c);}
for(int i=1;i<=m;i++) scanf("%d",q+i);
maxp[rt=0]=sum=n;//初始化
getrt(1,0),getrt(rt,0);//找重心
divide(rt);//点分治
for(int i=1;i<=m;i++) if(ans[i]) puts("AYE");else puts("NAY");
return 0;
}

skkyk:点分治的更多相关文章

  1. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  2. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  3. [poj1741][tree] (树/点分治)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  4. 【教程】简易CDQ分治教程&学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  5. BZOJ 3262 陌上花开 ——CDQ分治

    [题目分析] 多维问题,我们可以按照其中一维排序,然后把这一维抽象的改为时间. 然后剩下两维,就像简单题那样,排序一维,树状数组一维,按照时间分治即可. 挺有套路的一种算法. 时间的抽象很巧妙. 同种 ...

  6. BZOJ 1176 [Balkan2007]Mokia ——CDQ分治

    [题目分析] 同BZOJ2683,只需要提前处理s对结果的影响即可. CDQ的思路还是很清晰的. 排序解决一维, 分治时间, 树状数组解决一维. 复杂度是两个log [代码] #include < ...

  7. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  8. HDU5977 Garden of Eden(树的点分治)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...

  9. Tsinsen A1493 城市规划(DP + CDQ分治 + NTT)

    题目 Source http://www.tsinsen.com/A1493 Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在 ...

随机推荐

  1. 「漏洞预警」Apache Flink 任意 Jar 包上传导致远程代码执行漏洞复现

    漏洞描述 Apache Flink是一个用于分布式流和批处理数据的开放源码平台.Flink的核心是一个流数据流引擎,它为数据流上的分布式计算提供数据分发.通信和容错功能.Flink在流引擎之上构建批处 ...

  2. SqlServer性能优化,查看CPU、内存占用大的会话及SQL语句

    1,查看CPU占用量最高的会话及SQL语句   select spid,cmd,cpu,physical_io,memusage, (select top 1 [text] from ::fn_get ...

  3. swiper手滑导航圆点不同步

    // 滚动图 var mySwiper = new Swiper('.swiper-container', { // 如果需要分页器 pagination: { el: '.swiper-pagina ...

  4. django 做 migrate 时 表已存在的处理

    在开发web的时候,如果是以前已存在的项目,项目下载下来后,为了使用测试库的数据,会直接将整个测试库(如sqlite3)拿到本机来.这种情况下,如果执行的顺序不对,很容易在执行migrate的时候出现 ...

  5. C#语法基础----变量 符号 数据转换

    变量的作用:为了更好的管理内存数据,不同类型的数据存放在不同的内存块中. 变量的特点:不同数据类型占用的存储空间大小不一样. 变量的意义:内存地址是一串十六进制数,非常不好记忆,通过变量可以快速找到数 ...

  6. 为什么 Go 标准库中有些函数只有签名,没有函数体?

    如果你看过 Go 语言标准库,应该有见到过,有一些函数只有签名,没有函数体.你有没有感觉到很奇怪?这到底是怎么回事?我们自己可以这么做吗?本文就来解密它. 首先,函数肯定得有实现,没有函数体,一定是在 ...

  7. Jenkinsfile构建docker镜像

    pipeline { agent any stages { stage('preparation') { steps { echo "workspace: ${WORKSPACE}" ...

  8. Java中的String为什么要设计成不可变的?

    一.不可变类和不可变对象 Normally,you create an object and allow its contents to be changed later.However ,occas ...

  9. IntelliJ中Git突然不能用,报错 xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)

    记录一个昨天碰到的问题以及解决方法,希望对碰到一样问题的你有用! 昨天升级了一下Mac OS,重启后再打开IntelliJ,突然Git就不能用了,报了下面这样的错: 开始以为是不是Git出了问题,打开 ...

  10. SpringCloud的入门学习之概念理解、Hystrix断路器

    1.分布式系统面临的问题,复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败. 2.什么是服务雪崩? 答:多个微服务之间调用的时候,假设微服务A调用微服务B和微服务 ...