poj1741 树上的点分治
题意:
一棵10000个点的树,每条边的长不超过1000,给定一个值k,问距离不超过k的点对数有多少。(多组数据)
输入样例:
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0 输出样例:
8 ————————————————————————————————————————————————————————————————————————————
这个题目是在CODEVS 2756 树上的路径 的学习过程中看到别人的题解的过程中看到的,这个题相对简单,是做那个题的基础。基本上是人家的代码,和抄也差不了多少。是学习树上的点分治的一个基础题。
根据一个大神漆子超的论文,树上的分治可以分为点分治,边分治和链分治。点分治最差log,边分治最差n。而链分治是最好的,不过没有学会,有空再从网上找来学习一下,就是只学习点皮毛,对自己做题思路也是一种扩展。
点分治,就是在树中去掉一个点,从而使原来的树变成更小的树,从而达到分治的目的。为了防止极差情况的出现,提高分治的效率,最好的分治点是树的重心(去掉该点后,所得最大子树最小)。所在就有了点分治的方法。
1、深搜,得到各个点为根的子树的大小和各个点的最大子树的大小
2、二次深搜,得到去掉各个点得到的最大子树的大小,从而通过遍历得到重心。
3、应用问题与重心的关系进行分治。
(本题中:
3.1、计算通过重心且不超过k的点对数(包含重边)。
3.2、减去过重心且不超过k的点对数(即有重边的点对数)。
3.3、标明已查到的重心(vis),在新生成的子树中重新进行上述操作,完成分治。
) 边分治,没有做过,不过据漆子超说,是去掉一条过,把树分成2个树,完成分治。个人愚见,如果不是星型那种极个别的情况也可以实现log。
————————————————————————————————————————————————————————————————————————————
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm> using namespace std;
const int maxn=; int n,k,ans;
struct edge
{
int u,v,w,next;
}e[*maxn];
int head[maxn],js,jst,mi,root;
int siz[maxn],mx[maxn],dis[maxn];
bool vis[maxn];
void init()
{
memset(head,,sizeof(head));
memset(vis,,sizeof(vis));
js=;
ans=;
}
void readint(int &x)
{
int f=;
char c=getchar();
for(;c<''||c>'';c=getchar())if(c=='-')f=-f;
x=;
for(;c>=''&&c<='';c=getchar())x=x*+c-'';
x=x*f;
}
void addage(int u,int v,int w)
{
e[++js].u=u;e[js].v=v;e[js].w=w;
e[js].next=head[u];head[u]=js;
}
void dfssize(int u,int fa)
{
siz[u]=;mx[u]=;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=fa && !vis[v])
{
dfssize(v,u);
siz[u]+=siz[v];
if(siz[v]>mx[u])mx[u]=siz[v];
}
}
}
void dfsroot(int r,int u,int f)
{
if(siz[r]-siz[u]>mx[u])mx[u]=siz[r]-siz[u];
if(mx[u]<mi)
{
mi=mx[u];
root=u;
}
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=f &&!vis[v])
{
dfsroot(r,v,u);
}
}
}
void dfsdis(int u,int d,int f)
{
dis[jst++]=d;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=f && !vis[v])
dfsdis(v,d+e[i].w,u);
}
}
int calc(int u,int d)
{
int anst=;
jst=;
dfsdis(u,d,);
sort(dis,dis+jst);
int i=,j=jst-;
while(i<j)
{
while(dis[i]+dis[j]>k && i<j)j--;
anst+=j-i;
i++;
}
return anst;
}
void dfs(int u)
{
mi=n;
dfssize(u,);
dfsroot(u,u,);
ans+=calc(root,);
vis[root]=;
for(int i=head[root];i;i=e[i].next)
{
int v=e[i].v;
if(!vis[v])
{
ans-=calc(v,e[i].w);
dfs(v);
} } }
int main()
{
while(scanf("%d%d",&n,&k)==)
{
if(!n && !k)break;
init();
for(int u,v,w,i=;i<n;i++)
{
readint(u);readint(v);readint(w);
addage(u,v,w);addage(v,u,w);
}
dfs();
printf("%d\n",ans);
}
return ;
}
poj1741 树上的点分治的更多相关文章
- POJ-1741 树上分治--点分治(算法太奇妙了)
给你1e5个节点的树,(⊙﹏⊙) 你能求出又几对节点的距离小于k吗??(分治NB!) 这只是一个板子题,树上分治没有简单题呀!(一个大佬说的) #include<cstdio> #incl ...
- [POJ1741]树上的点对 树分治
Description 给一棵有n个节点的树,每条边都有一个长度(小于1001的正整数). 定义dist(u,v)=节点u到节点v的最短路距离. 给出一个整数k,我们称顶点对(u,v)是合法的当且仅当 ...
- poj1741 树上的分治
题意是说给了n个点的树n<=10000,问有多少个点对例如(a,b)他们的之间的距离小于等于k 采用树的分治做 #include <iostream> #include <cs ...
- poj1741 树上距离小于等于k的对数 点分治 入门题
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- POJ 1741 树上的点分治
题目大意: 找到树上点对间距离不大于K的点对数 这是一道简单的练习点分治的题,注意的是为了防止点分治时出现最后分治出来一颗子树为一条直线,所以用递归的方法求出最合适的root点 #include &l ...
- POJ1741 Tree(树分治——点分治)题解
题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...
- poj1741 Tree(点分治)
题目链接:http://poj.org/problem?id=1741 题意:求树上两点之间距离小于等于k的点对的数量 思路:点分治模板题,推荐一篇讲的非常好的博客:https://blog.csdn ...
- POJ1741 tree 【点分治】
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 25286 Accepted: 8421 Description ...
- [POJ1741]Tree(点分治模板)
传送门 良心解析 其实以前在求某段序列上的区间统计问题时就碰到过类似于这样的思想. 当时的区间统计问题思路大致是这样: 选取一个点作为中间点,从这个点的左边和右边统计出满足条件的点对.然后当前的中间点 ...
随机推荐
- [原创]cocos2d-x研习录-第二阶 概念类之导演类(CCDirector)
CCDirector类是游戏的组织和控制中心(总指挥),它控制着主屏幕的显示.场景的切换和显示,以及游戏的开始.结束和暂停.它的继承关系图如下: CCDirector继承自基类CCObject, ...
- JSBinding + SharpKit / 编译 Cs 成 Js
轻轻一点菜单:[JSB | Compile Cs to Js] 主要产出:StreamingAssets/JavaScript/SharpkitGeneratedFiles.javascript,你的 ...
- 移动POS机
1.怎么识别手刷机所属公司是否是二清公司,甚至是多清 去银行,手机银行,网上银行查询该笔款是哪里汇出的,如果是银行或合法支付公司汇出,一般为一清机,如果是个人或无支付牌照的支付公司,一般为二清机: 已 ...
- linux服务之maven
curl -O http://mirrors.noc.im/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip [root@d ...
- Dictionary 序列化与反序列化
[转:http://blog.csdn.net/woaixiaozhe/article/details/7873582] 1.说明:Dictionary对象本身不支持序列化和反序列化,需要定义一个继承 ...
- WCF: 没有终结点在侦听可以接受消息的 这通常是由于不正确的地址或者 SOAP 操作导致的。
问题: 由于我这里的wcf服务是采用“BasicHttpBinding”的方式,即安全绑定模式,客户端在引用这个服务后所生成的终结点配置(endpoint )就变成了<endpoint ...
- fedora 配置
静态ip配置 vi /etc/sysconfig/network-scripts/ifcfg-ens33 [root@localhost network-scripts]# cat ifcfg-ens ...
- [家里蹲大学数学杂志]第269期韩青编《A Basic Course in Partial Differential Equations》 前五章习题解答
1.Introduction 2.First-order Differential Equations Exercise2.1. Find solutons of the following inti ...
- mybatis配置优化
1.加入日志log4j 1)加入jar包:log4j-1.2.17.jar 2)加入log4j配置文件: 可以使properties或者xml形式 log4j.rootLogger = DEBUG,C ...
- Xcode取消某条警告
[Xcode取消某条警告] 像下面这样,把双引号“”内的内容替成实际的警告类型即可. #pragma clang diagnostic push #pragma clang diagnostic ...