[bzoj1468][poj1741]Tree_点分治】的更多相关文章

Tree bzoj-1468 poj-1741 题目大意:给你一颗n个点的树,求树上所有路径边权和不大于m的路径条数. 注释:$1\le n\le 4\cdot 10^4$,$1\le m \le 10^9$. 想法:GXZlegend给高一讲点分治,去听了之后的第一道模板题. 我们对于一类树上统计问题,除了强大的树形dp之外,我们还有分治.今天听的是点分治: 就是说,我们将所有的链关于一个点分划成两类:过这个点的链,和不过这个点的链.这个点就是根节点,我在任意两颗子树中拎出两个点,他们之间的链…
可以说是点分治第一题,之前那道的点分治只是模模糊糊,做完这道题感觉清楚了很多,点分治可以理解为每次树的重心(这样会把数分为若干棵子树,子树大小为log级别),然后统计包含重心的整个子树的值减去各个子树的值,这样算出的就是与这个重心有关的情况的答案,比如这道题,求路径,那么就考虑在重心所在的子树中所有的路径减去不过重心的路径就是过重心的路径了.之前重心没找对...poj时间卡的紧就T了.. #include <iostream> #include <algorithm> #inclu…
POJ1741 Tree + BZOJ1468 Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dist(u,v)=The min distance between node u and v. Give an integer k,for every pair (u,v) of vertices is called valid i…
Problem Tree 题目大意 给一棵树,有边权.求树上距离小于等于K的点对有多少. 解题分析 点分治.对每一棵子树进行dfs,求出每棵子树的重心,继而转化为子问题. 对于经过根的路径i--j,令dep为到根距离,那么需求出dep[i]+dep[j]<=k,且i,j属于不同子树,可以求其补集,求出属于同一子树的对答案贡献. 参考程序 #include <map> #include <set> #include <stack> #include <queu…
1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] Description 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K Input N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k Output 一行,有多少对点之间的距离小于等于k Sample Input 7 1 6 13 6…
题意是说给了n个点的树n<=10000,问有多少个点对例如(a,b)他们的之间的距离小于等于k 采用树的分治做 #include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <vector> using namespace std; ; ],to[maxn*],numofE,dist[maxn*]; void add(int u…
树分治之点分治入门 所谓点分治,就是对于树针对点的分治处理 首先找出重心以保证时间复杂度 然后递归处理所有子树 对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况 路径过当前根 路径在子树中(递归处理) 那么关键就是如何计算第一种情况 设d[i]表示点i到当前根rt的距离,可以将d数组排序后线性复杂度求 然而此时会有些点对是在同一棵子树中,这些情况要减去 注意每次递归都要找一次重心以保证效率 这样复杂度就是O(nlog2n) Code #include <cstdio>…
[题意]给定带边权树,求两点距离<=k的点对数.n<=40000. [算法]点分治 [题解]对于一个区域,选择其重心x作为根,则划分出来的每棵子树都是子区域,可以证明至多划分log n次(通过vis[]划分区域).每次划分所有点都扫描一次,所以仅遍历的复杂度是O(n log n). 对于本题,将点x的所有子树节点dis处理出来后排序,然后用双指针法易得<=k的点对数. 但是,这样会把来自同一子树的路径也计算进去,需要减去.来自同一子树y的距离<=k的路径的数量等同于子树y内路径的距…
题意:有一棵树,每条边有一个距离,求dis(u,v)<=k的点的对数 题解:树分治,对于一颗树上的两点,要么在同一颗子树上,要么在不同子树上,要么一个点是根,另一个在某一子树上,对于第一种情况我们可以通过递归来变成第二种或者第三种情况.我们对于某一颗子树来说我们先统计dis[u]+dis[v]<=k的点的对数,然后把该子树的所有子节点为根的这颗子树中dis[u]+dis[v]<=k的点的对数删去,因为在递归到后面会计算重复(这是第一种情况),所以这样就得到了该子树的满足条件的点对数,那么…
树的点分治 给出详细的讲解!!点这里打开论文-分治算法在树的路径问题中的应用 本题目是他讲的第一个例题: 我的理解:每次都找树的重心,计算以重心为根的子树之间所贡献的答案.不断这样下去:如果这棵树是一条链,那么就和快排,归并的线性分治法一样了.如果不是一条链那么就相当于,选中一个点,标记为使用过.然后树会被这个节点划分成多棵子树.然后这样分治下去.思想好理解.但是代码不是很好想!详见注解. #include <stdio.h> #include <string.h> #includ…