题目链接:https://vjudge.net/problem/POJ-1741

题意:给出一棵树,求出树上距离不超过k的点对数量。

思路:点分治经典题。先找重心作为树根,然后求出子树中所有点到重心的距离dis[i],那么所有组合为dis[i]+dis[j]<=k,其中不合法组合为在重心的同一个子树内的情况,所以要减去在重心的子树中仍满足dis[i]+dis[j]<=k的情况。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; const int inf=0x3f3f3f3f;
const int maxn=;
struct node1{
int v,w,nex;
}edge[maxn<<]; struct node2{
int x,y;
}arr[maxn]; int n,k,cnt,ans,head[maxn],sz[maxn],mson[maxn],Min,root,size;
int vis[maxn],t,tt,dis[maxn],pre[maxn]; void adde(int u,int v,int w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void getroot(int u,int fa){
sz[u]=,mson[u]=;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
if(vis[v]||v==fa) continue;
getroot(v,u);
sz[u]+=sz[v];
if(sz[v]>mson[u]) mson[u]=sz[v];
}
if(size-sz[u]>mson[u]) mson[u]=size-sz[u];
if(mson[u]<Min) Min=mson[u],root=u;
} void getdis(int u,int fa,int len){
dis[++t]=len;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
if(vis[v]||v==fa) continue;
getdis(v,u,len+edge[i].w);
}
} void solve(int x,int y,int f){
t=;
getdis(x,,y);
sort(dis+,dis+t+);
tt=,dis[]=-,pre[]=;
for(int i=;i<=t;++i)
if(dis[i]!=dis[i-]) arr[++tt].x=dis[i],arr[tt].y=,pre[tt]=pre[tt-]+;
else ++arr[tt].y,++pre[tt];
for(int i=;i<=tt&&arr[i].x<=k/;++i)
ans+=(arr[i].y-)*arr[i].y/*f;
for(int i=;i<=tt&&arr[i].x<k/;++i){
int l=i+,r=tt,mid;
while(l<=r){
mid=(l+r)>>;
if(arr[i].x+arr[mid].x<=k) l=mid+;
else r=mid-;
}
ans+=(arr[i].y)*(pre[r]-pre[i])*f;
}
} void fenzhi(int u,int ssize){
vis[u]=;
solve(u,,);
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
if(vis[v]) continue;
solve(v,edge[i].w,-);
Min=inf,root=;
size=sz[v]<sz[u]?sz[v]:(ssize-sz[u]);
getroot(v,);
fenzhi(root,size);
}
} int main(){
while(scanf("%d%d",&n,&k),n||k){
cnt=ans=;
for(int i=;i<=n;++i)
head[i]=,vis[i]=;
for(int i=;i<n;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
adde(v,u,w);
}
Min=inf,root=,size=n;
getroot(,);
fenzhi(root,n);
printf("%d\n",ans);
}
}

poj1741(入门点分治)的更多相关文章

  1. [bzoj1468][poj1741]Tree_点分治

    Tree bzoj-1468 poj-1741 题目大意:给你一颗n个点的树,求树上所有路径边权和不大于m的路径条数. 注释:$1\le n\le 4\cdot 10^4$,$1\le m \le 1 ...

  2. poj1741 (点分治)

    Problem Tree 题目大意 给一棵树,有边权.求树上距离小于等于K的点对有多少. 解题分析 点分治.对每一棵子树进行dfs,求出每棵子树的重心,继而转化为子问题. 对于经过根的路径i--j,令 ...

  3. poj1741 树上的分治

    题意是说给了n个点的树n<=10000,问有多少个点对例如(a,b)他们的之间的距离小于等于k 采用树的分治做 #include <iostream> #include <cs ...

  4. [POJ1741]Tree(点分治)

    树分治之点分治入门 所谓点分治,就是对于树针对点的分治处理 首先找出重心以保证时间复杂度 然后递归处理所有子树 对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况 路径过当前根 ...

  5. 【BZOJ】1468: Tree(POJ1741) 点分治

    [题意]给定带边权树,求两点距离<=k的点对数.n<=40000. [算法]点分治 [题解]对于一个区域,选择其重心x作为根,则划分出来的每棵子树都是子区域,可以证明至多划分log n次( ...

  6. POJ1741 经典树分治

    题意:有一棵树,每条边有一个距离,求dis(u,v)<=k的点的对数 题解:树分治,对于一颗树上的两点,要么在同一颗子树上,要么在不同子树上,要么一个点是根,另一个在某一子树上,对于第一种情况我 ...

  7. POJ-1741(树分治)

    树的点分治 给出详细的讲解!!点这里打开论文-分治算法在树的路径问题中的应用 本题目是他讲的第一个例题: 我的理解:每次都找树的重心,计算以重心为根的子树之间所贡献的答案.不断这样下去:如果这棵树是一 ...

  8. [poj1741]Tree(点分治+容斥原理)

    题意:求树中点对距离<=k的无序点对个数. 解题关键:树上点分治,这个分治并没有传统分治的合并过程,只是分成各个小问题,并将各个小问题的答案相加即可,也就是每层的复杂度并不在合并的过程,是在每层 ...

  9. POJ1741(点分治)

    分治的时候SZ感觉是错的--但是貌似第一次找好重心就够了,之后SZ别太离谱就不会T,重心随一随缘就好-- #include <cstdio> #include <cstring> ...

随机推荐

  1. Educational Codeforces Round 33 (Rated for Div. 2) B题

    B. Beautiful Divisors Recently Luba learned about a special kind of numbers that she calls beautiful ...

  2. Luogu P2824 [HEOI2016/TJOI2016]排序 线段树+脑子

    只会两个$log$的$qwq$ 我们二分答案:设答案为$ans$,则我们把$a[i]<=ans$全部设成$0$,把$a[i]>ans$全部设成$1$,扔到线段树里,这样区间排序(升序)就是 ...

  3. 简易的学生成绩管理系统(C++实现)

    最近浅显的学习了C++的基础知识,想来练练手,于是就用单链表写了最经典的小项目,存粹学习,所以就在控制台下写了,写的有点简陋,码了大概400多行. 下面上代码: #include <cstdli ...

  4. UVA 247 Calling Circles —— (强连通分量模板题)

    第一个强连通分量的题. 题意:有一堆人,a给b打电话表示a有一条向b的边,一个强连通分量代表一个电话圈,把每个电话圈里的人在一行内输出出来. 直接上模板即可,但是要注意把string用map映射一下的 ...

  5. 事务四大特性(ACID)

    事务的概念:事务是指逻辑上的一组操作,这组操作要么同时完成要么同时不完成. 事务的管理:默认情况下,数据库会自动管理事务,管理的方式是一条语句就独占一个事务. 如果需要自己控制事务也可以通过如下命令开 ...

  6. 【转】mysql基础汇总

    mysql基础知识语法汇总整理(二)  原文:https://www.cnblogs.com/cxx8181602/p/9525950.html 连接数据库操作 /*连接mysql*/ mysql - ...

  7. dubbo异常filter

    dubbo请求调用过程分析 https://blog.csdn.net/javahongxi/article/details/72876694 浅谈dubbo的ExceptionFilter异常处理  ...

  8. Repeater, DataList, 和GridView的区别及使用

    从对象层次图可以看出,Repeater是最轻最小的控件,它仅仅继承了基本控件的功能,包括ID属性.子控件集合等.另一方面,DataList和DataGrid则继承了WebControl功能,包括样式和 ...

  9. js五彩小球

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. python之scrapy模块pipelines

    1.知识点 """" pipelines使用: 1.在spiders里面使用yield生成器 list_li = response.xpath("// ...