首先给出定义

点分治是一种处理树上路径的工具

挂出一道题目来:Master of Subgraph

这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生

这道题目,假如我们利用暴力的方法去求解的话

实际上是对每个节点进行一次dfs,这样的话会发现复杂度为O(N^2)也就是再9e6左右,再加上常数M/64,复杂度根本不够(9e9)

我们可以利用点分治去优化复杂度

点分治的原理就是树上的路径产生的答案,不是在经过这个节点的就是在不经过这个节点的,那我们找到树的重心的话,就能够算出来经过该点的所有答案,然后依次递归大约logN层,这样复杂度就变成了NlogN的程度,也就是3e4*1e3=3e7加上常数,再加上时间的宽限,完全够用

所以点分治就是树上分治的一种,减小重复计算的东西,不断逐步缩小子树的计算

其中一般来说要开 一个父节点数组,一个儿子数数组,来计算重心的位置

然后就是点分治,跟递归差不多就是要去计算答案

然后就是利用solve函数,每次点分治计算树根,然后依次处理子树的重心节点然后继续递归继续分治

 #include <iostream>
 #include <cstring>
 #include <vector>
 #include <bitset>

 ;
 ;

 int E[MAXN][MAXN];
 int all[MAXN];

 int f[MAXN],son[MAXN],root,tot;
 /*
     分别代表f[x]的两侧孩子数目的最大值,重心的孩子数目最小
     son代表以x为根的孩子数目
     root是被移动的根
     tot是当前根的孩子总数
  */
 bool vis[MAXN];

 std::bitset<MAXM>b[MAXN],ans;

 int n,m,val[MAXN];

 void dfs(int x,int fa){
     /* dfs搜索树,将根移动到树的重心,降低dp层数 */
     f[x] = ;
     /* 标记孩子数目为0 */
     son[x] = ;
     /* 计算孩子数目 */
     ; i <= all[x]; i++)
     {
         int y=E[x][i];
         if(!vis[y] && y!=fa)
         {
             dfs(y,x);
             /* 递归进入子数 */
             f[x] = std::max(f[x],son[y]);
             /* 计算子树中孩子数目最多的子树孩子数 */
             son[x]+=son[y];
             /* 累加孩子数目 */
         }
     }
     f[x]=std::max(f[x],tot-f[x]);
     /* 计算该根节点最大孩子数其余侧的数目中两边的最大值 */
     if(f[x]<f[root]) root=x;
     /* 移动根节点,寻找重心 */
 }

 void getdp(int x, int fa){
     b[x]<<=val[x];
     /* 累加val[x] */
     son[x]=;

     ;i<=all[x];i++)
     {
         int y=E[x][i];
         if(!vis[y] && y!=fa)
         {
             b[y]=b[x];
             getdp(y,x);
             son[x]+=son[y];
             b[x]|=b[y];
         }
     }
 }

 void solve(int x){
     vis[x] = true;
     b[x] = ;
     getdp(x,);
     /* 以某一点为根进行点分治 */
     ans|=b[x];
     /* 累加答案 */

     ;i<=all[x];i++)
     {
         /* 子树递归进行点分治 */
         int y=E[x][i];
         if(!vis[y])
         {
             tot = son[y];
             root = ;
             dfs(y,x);
             /* 先寻找树根 */
             solve(root);
             /* 递归分治 */
         }
     }
 }

 int main(){
     int T;
     std::cin>>T;
     while(T--)
     {
         scanf("%d%d",&n,&m);
         ;i<=n;i++) all[i]=;
         ans.reset();
         memset(vis,,sizeof(vis));
         ;i<n;i++)
         {
             int x,y;
             scanf("%d%d",&x,&y);
             E[x][++all[x]]=y;
             E[y][++all[y]]=x;
         }
         ;i<=n;i++)
         {
             scanf("%d",&val[i]);
         }

         f[] = n+;
         tot=n;
         dfs(,root);
         solve(root);
         ;i<=m;i++)
         {
             printf("%d",(int)ans[i]);
         }
         puts("");
     }
     ;
 }

算法学习分析-点分治 HDU 6269 Master of Subgraph的更多相关文章

  1. HDU 6268 Master of Subgraph (2017 CCPC 杭州 E题,树分治 + 树上背包)

    题目链接  2017 CCPC Hangzhou  Problem E 题意  给定一棵树,每个点有一个权值,现在我们可以选一些连通的点,并且把这点选出来的点的权值相加,得到一个和. 求$[1, m] ...

  2. hdu 6268 Master of Subgraph(点分治+bitset)

    You are given a tree with n nodes. The weight of the i-th node is wi. Given a positive integer m, no ...

  3. <2014 05 09> Lucida:我的算法学习之路

    [转载] 我的算法学习之路 关于 严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口——况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以 ...

  4. 算法学习之C语言基础

    算法学习,先熟悉一下C语言哈!!! #include <conio.h> #include<stdio.h> int main(){ printf(+); getch(); ; ...

  5. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  6. 二次剩余Cipolla算法学习笔记

    对于同余式 \[x^2 \equiv n \pmod p\] 若对于给定的\(n, P\),存在\(x\)满足上面的式子,则乘\(n\)在模\(p\)意义下是二次剩余,否则为非二次剩余 我们需要计算的 ...

  7. 算法学习之快速排序的C语言实现

    近几天在学习简单算法,今天看了一个快速排序和堆排序,堆排序还没搞懂,还是先把快速排序搞清楚吧 教程网上一艘一大堆,这里选择一个讲的比较通俗的的一个吧: http://blog.csdn.net/mor ...

  8. 3.2_k-近邻算法案例分析

        k-近邻算法案例分析 本案例使用最著名的”鸢尾“数据集,该数据集曾经被Fisher用在经典论文中,目前作为教科书般的数据样本预存在Scikit-learn的工具包中. 读入Iris数据集细节资 ...

  9. Reinforcement Learning Q-learning 算法学习-2

    在阅读了Q-learning 算法学习-1文章之后. 我分析了这个算法的本质. 算法本质个人分析. 1.算法的初始状态是随机的,所以每个初始状态都是随机的,所以每个初始状态出现的概率都一样的.如果训练 ...

随机推荐

  1. hihocoder-1274 自行车架(高维dp)

    时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi的宿舍楼下有一块用于停自行车的区域.平时自行车都停得非常杂乱,于是楼长打算去买一排自行车架用来停车.自行车架一般有P个 ...

  2. Android 中对于图片的内存优化方法

    Android 中对于图片的内存优化方法,需要的朋友可以参考一下     1. 对图片本身进行操作 尽量不要使用 setImageBitmap.setImageResource. BitmapFact ...

  3. 机器学习 Generative Learning Algorithm (B)

    Naive Bayes 在GDA模型中,特征向量x是连续的实数向量,在这一讲里,我们将要讨论另外一种算法用来处理特征向量x是离散值的情况. 我们先考虑一个例子,用机器学习的方法建立一个垃圾邮件过滤器, ...

  4. ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587 题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后 ...

  5. 霍夫变换Hough

    http://blog.csdn.net/sudohello/article/details/51335237 霍夫变换Hough 霍夫变换(Hough)是一个非常重要的检测间断点边界形状的方法.它通 ...

  6. IronPython+Anthem.Net也玩 Ajax!

    在 IronPython 搭建的项目中(也可以是和 C# 的混合项目,详见我前一篇 post),可以使用 Anthem.NET 来轻松实现 Ajax 功能. 下面我简单的演示一个例子:在页面上我们分别 ...

  7. python mysql 查询返回字典结构

    cur = self.conn.cursor(MySQLdb.cursors.DictCursor)加上MySQLdb.cursors.DictCursor可以返回字典结构 {列名:值} class ...

  8. 通过设置swift中container的ACL提供匿名访问及用户授权读取服务

    在上层使用swift提供的云存储服务的过程中,提出了无需验证的使用需求. 在参考了:http://my.oschina.net/alanlqc/blog/160196(curl命令操作) 官方文档: ...

  9. Go和HTTPS

    转自:http://tonybai.com/2015/04/30/go-and-https/ 近期在构思一个产品,考虑到安全性的原因,可能需要使用到HTTPS协议以及双向数字证书校验.之前只是粗浅接触 ...

  10. MS-SQL循环、随机数

    ---创建视图 create view myview as select re=rand() --自定义函数:取得指定范围的随机数 create function mydata( @a int, @b ...