树分治入门

poj1741是男人八题之一,经典的树分治的题目
这里用到的是点分治
核心思想是我们把某个点i作为根,把路径分为过点i和不过点i
先统计过点i这样的路径数,然后在统计其子树中的答案,这样就不断地划分成规模较小子问题。
要使划分最优,我们每次都选的是树的重心

 type node=record
len,next,po:longint;
end; var e:array[..] of node;
w,p,d,a,size:array[..] of longint;
v:array[..] of boolean;
root,sum,n,t,ans,k,i,x,y,z,len:longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) div ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
y:=a[i];
a[i]:=a[j];
a[j]:=y;
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure add(x,y,z:longint);
begin
inc(len);
e[len].po:=y;
e[len].len:=z;
e[len].next:=p[x];
p[x]:=len;
end; procedure getroot(x,fa:longint); //选择重心
var i,y:longint;
begin
i:=p[x];
size[x]:=;
w[x]:=;
while i<> do
begin
y:=e[i].po;
if (not v[y]) and (y<>fa) then
begin
getroot(y,x);
size[x]:=size[x]+size[y];
w[x]:=max(w[x],size[y]);
end;
i:=e[i].next;
end;
w[x]:=max(w[x],sum-size[x]);
if w[x]<w[root] then root:=x;
end; procedure deep(x,fa:longint);
var i,y:longint;
begin
inc(t);
a[t]:=d[x];
i:=p[x];
while i<> do
begin
y:=e[i].po;
if not v[y] and (y<>fa) then
begin
d[y]:=d[x]+e[i].len;
deep(y,x);
end;
i:=e[i].next;
end;
end; function calc(x,now:longint):longint;
var i,l,r:longint;
begin
t:=;
d[x]:=now;
calc:=;
deep(x,);
sort(,t);
l:=;
r:=t;
while l<r do
begin
if a[l]+a[r]<=k then
begin
calc:=calc+r-l;
inc(l);
end
else dec(r);
end;
end; procedure work(x:longint);
var i,y:longint;
begin
ans:=ans+calc(x,);
i:=p[x];
v[x]:=true;
while i<> do
begin
y:=e[i].po;
if not v[y] then
begin
ans:=ans-calc(y,e[i].len); //之前的计算会导致lca不为root的点对被算入,实际它们的路径不过重心,这里要减去
sum:=size[y];
root:=;
getroot(y,);
work(root);
end;
i:=e[i].next;
end;
end; begin
readln(n,k);
while n<> do
begin
len:=;
fillchar(p,sizeof(p),);
for i:= to n- do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
fillchar(v,sizeof(v),false);
sum:=n;
w[]:=;
getroot(,);
ans:=;
work(root);
writeln(ans);
readln(n,k);
end;
end.

bzoj2152是更水的树分治……

poj1741 bzoj2152的更多相关文章

  1. 点分治Day1

    树套树Day2暂且搁置...因为Day1的题我各种不会做... 唯一过了一道还是整体二分过的... 我们来一点愉快的算法,先不考虑数据结构这种骚东西了 毕竟还在发烧,就先码码这几天在搞的点分治吧 hx ...

  2. 【poj1741】 Tree

    http://poj.org/problem?id=1741 (题目链接) 题意 给出一个n个节点的带权树,求树上距离不超过K的所有点对的个数. solution  点分治裸题.所谓的点分治,就是对于 ...

  3. 【bzoj2152】 聪聪可可

    http://www.lydsy.com/JudgeOnline/problem.php?id=2152 (题目链接) 题意 给出一棵n个节点的带权树,求有多少点对的距离是3的倍数. solution ...

  4. 【BZOJ2152】聪聪可可(点分治)

    [BZOJ2152]聪聪可可(点分治) 题面 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电 ...

  5. POJ1741 Tree(树分治——点分治)题解

    题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...

  6. BZOJ2152 [国家集训队] 聪聪可可 [点分治]

    题目传送门 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 5237  Solved: 2750[Submit][Status][Discuss ...

  7. 【POJ1741】Tree(点分治)

    [POJ1741]Tree(点分治) 题面 Vjudge 题目大意: 求树中距离小于\(K\)的点对的数量 题解 完全不觉得点分治了.. 简直\(GG\),更别说动态点分治了... 于是来复习一下. ...

  8. POJ1741 Tree + BZOJ1468 Tree 【点分治】

    POJ1741 Tree + BZOJ1468 Tree Description Give a tree with n vertices,each edge has a length(positive ...

  9. BZOJ2152 聪聪可可 【点分治】

    BZOJ2152 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)--遇到这种问 ...

随机推荐

  1. Oracle之Merge用法

    Merge用来从一个表中选择一些数据更新或者插入到另一个表中.而最终是用更新还是用插入的方式取决于该语句中的条件. 下面我们简单的举一个例子: SQL)) 表已创建. SQL)) 表已创建. SQL, ...

  2. PHP session 失效不传递的解决办法

    PHP中,session不能传递到下一个页面去,一般有两种情况: 我们先写个php文件:<?=phpinfo()?>, 传到服务器去看看服务器的参数配置. 转到session部分,看到se ...

  3. web页面的生命周期

    1.先上几张原理图着重理解: 现在针对第四副图原理进行解析: 流程: 1.浏览器发送请求 2.服务器软件(IIS)接收,它最终的目的就是为了向客户输出它请求的动态页面生成的html代码. 3.服务器不 ...

  4. PHP中刷新输出缓冲

    http://www.cnblogs.com/mutuan/archive/2012/03/18/2404957.html PHP中刷新输出缓冲buffer是一个内存地址空间,Linux系统默认大小一 ...

  5. IP-MAC绑定导致网络故障

    前段时间将一台服务器A的服务迁移至了另外一台服务器B,外网IP地址也顺带迁移过来了,结果网络出现了问题. 其中内网是畅通的,但是外网IP怎么都连不上另外一台路由C(B和C是在一个交换机下的,网段也相同 ...

  6. HTML_常见命令学习笔记

    1. java类中的这段代码 out.println(" <div class='line'>"); out.println(" <div align= ...

  7. Javascript中数组方法汇总

    Array.prototype中定义了很多操作数组的方法,下面介绍ECMAScript3中的一些方法: 1.Array.join()方法 该方法将数组中的元素都转化为字符串并按照指定符号连接到一起,返 ...

  8. 引用传递&值传递

    下面的程序阐述了值传递与应用传递的区别. package com.liaojianya.chapter1; /** * This program demonstrates the use of arr ...

  9. std::map的操作:插入、修改、删除和遍历

    using namespace std; std::map<int,int> m_map; 1.添加 for(int i=0;i<10;i++) { m_map.insert(mak ...

  10. Mysql备份数据库的一种方法

    今天添加了一个数据库自动备份的模块,mysql数据备份的方法有很多,可以对单个数据库备份,可以多个数据库备份,也可以对某一个表进行备份,可以只备份数据库的结构不备份数据,可以根据需要做不同处理,正好现 ...