做广告:

#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/44302921");
}

题意:

给你一棵无根树,求有多少点对之间距离<=K。

题解:

树分治。

然后对于一个重心X。我们把它的全部子树中的全部点存到结构体数组中。

结构体中存距离和子树编号。

第一遍sort,我们双指针扫哪些点对符合要求。

第二遍sort,我们把同一子树中还符合要求的点对数目删掉。

sort是O(nlogn)。处理是O(n)。

然后分治logn层,总时间复杂度O(nlog2n)

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 50100
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
struct Eli
{
int v,len,next;
}e[N<<1];
int head[N],cnt;
bool rem[N];
inline void add(int u,int v,int len)
{
e[++cnt].v=v;
e[cnt].len=len;
e[cnt].next=head[u];
head[u]=cnt;
}
int f[N],f2[N],son[N];
int TreeCenter,length;
int dfs1(int x,int p)
{
int i,v;
f[x]=f2[x]=0;
for(i=head[x];i;i=e[i].next)
{
v=e[i].v;
if(v==p||rem[v])continue;
int temp=dfs1(v,x);
if(temp>f[x])
{
f2[x]=f[x];
f[x]=temp;
son[x]=v;
}
else if(temp>f2[x])
f2[x]=temp;
}
return f[x]+1;
}
int g[N];
void dfs2(int x,int p)
{
int i,v;
if(max(f[x],g[x])<length)
{
length=max(f[x],g[x]);
TreeCenter=x;
}
for(i=head[x];i;i=e[i].next)
{
v=e[i].v;
if(v==p||rem[v])continue;
if(v==son[x])g[v]=max(g[x],f2[x])+1;
else g[v]=max(g[x],f[x])+1;
dfs2(v,x);
}
return ;
}
inline int get_TreeCenter(int x)
{
if(rem[x])return 0;
length=inf,g[x]=0;
dfs1(x,0),dfs2(x,0);
return TreeCenter;
}
struct Summorer
{
int a,b;
// 权值,子树标号
Summorer(int _a=0,int _b=0):a(_a),b(_b){}
}src[N];
inline int cmpa(Summorer a,Summorer b)
{
return a.a<b.a;
}
inline int cmpb(Summorer a,Summorer b)
{
return a.b==b.b? a.a<b.a:a.b<b.b;
}
int size[N];
void dfs3(int x,int p,int t,int len)
{
src[++cnt]=Summorer(len,t);
size[x]=1;
int i,v;
for(i=head[x];i;i=e[i].next)
{
v=e[i].v;
if(rem[v]||v==p)continue;
dfs3(v,x,t,len+e[i].len);
size[x]+=size[v];
}
return ;
}
int ans;
void work(int x,int n)
{
if(!n)return ;
rem[x=get_TreeCenter(x)]=1;
int num=0,i,j,k,v,p;
cnt=0;
for(i=head[x];i;i=e[i].next)
{
v=e[i].v;
if(rem[v])continue;
dfs3(v,x,++num,e[i].len);
}
sort(src+1,src+cnt+1,cmpa);
p=n;
for(i=0;i<=n;i++)
{
while(i<p&&src[i].a+src[p].a>m)p--;
if(i>=p)break;
ans+=(p-i);
}
sort(src+1,src+cnt+1,cmpb);
src[cnt+1].b=-1;
for(i=0;i<=n;i=j)
{
for(j=i+1;src[j].b==src[i].b;j++);
for(p=j-1,k=i;k<j;k++)
{
while(k<p&&src[k].a+src[p].a>m)p--;
if(k>=p)break;
ans-=(p-k);
}
}
for(i=head[x];i;i=e[i].next)
{
v=e[i].v;
if(rem[v])continue;
work(v,size[v]-1);
}
return ;
}
void init()
{
ans=cnt=0;
memset(rem,0,sizeof rem);
memset(head,0,sizeof head);
}
int main()
{
int i,a,b,c; while(scanf("%d%d",&n,&m),(n|m))
{
init();
for(i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
work(1,n-1);
printf("%d\n",ans);
} return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

【POJ1741】Tree 树分而治之 模板略?的更多相关文章

  1. POJ1741 Tree 树分治模板

    http://poj.org/problem?id=1741   题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数.   dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...

  2. POJ1741——Tree(树的点分治)

    1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...

  3. [poj1741][tree] (树/点分治)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

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

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

  5. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  6. poj 1744 tree 树分治

    Tree Time Limit: 1000MS   Memory Limit: 30000K       Description Give a tree with n vertices,each ed ...

  7. Tree( 树) 组件[4]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一.方法列表 //部分方法onClick : funct ...

  8. Tree( 树) 组件[3]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一. 事件列表很多事件的回调函数都包含'node'参数, ...

  9. Tree( 树) 组件[2]

    本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一. 异步加载如果想从数据库里获取导航内容, 那么就必须 ...

随机推荐

  1. enum可以做索引

    enum可以做索引 enum可以做索引, 配上虚函数,或者函数指针,可以实现上层的统一封装和快速索引. 点击(此处)折叠或打开 MoTbl.cpp #include <stdio.h> # ...

  2. 理解Windows内核模式与用户模式

     1.基础 执行 Windows 的计算机中的处理器有两个不同模式:"用户模式"和"内核模式". 依据处理器上执行的代码的类型,处理器在两个模式之间切换.应 ...

  3. IE6下position:fixed不支持问题及其解决方式

    IE6有诸多奇葩,不支持position:fixed就是当中之中的一个.所以在做一些比方固定在顶部或者底部或者固定元素的效果时须要考虑兼容IE6的这个问题.解决方式是用Ie6的hack. *html ...

  4. uva--562Dividing coins +dp

    题意: 给定一堆硬币,然后将他们分成两部分,使得两部分的差值最小;输出这个最小的差值. 思路: 想了好久都没想到一个合适的状态转移方程.后面看了别人的题解后,才知道能够转成背包问题求解. 我们将全部的 ...

  5. thinkPHP框架介绍(一)

    原文:thinkPHP框架介绍(一) 一.ThinkPHP的介绍 期间有对ThinkPHP框架在学习上的问题欢迎大家交流:QQ:812231134 MVC M - Model 模型           ...

  6. g++优化选项

    g++优化选项 g++优化选项 对于下面的这段代码: 1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> using namespace std; ...

  7. java过滤html标签函数

    public static String Html2Text(String inputString) {              String htmlStr = inputString; //含h ...

  8. python语言学习8——字符串和编码

    Unicode编码 计算机只能处理数字,如果要处理文本,就必须把文本转化为数字才能处理 有许多编码标准,但是不同的编码标准有时候会混乱,所以Unicode应运而生 Unicode把所有语言统一到一套编 ...

  9. Ubuntu 12.04更新源

    源地址:http://www.cnblogs.com/eastson/archive/2012/08/24/2654163.html 1.首先备份Ubuntu12.04源列表 sudo cp /etc ...

  10. 推荐一套.NET文档处理组件Spire.Office

    原文:推荐一套.NET文档处理组件Spire.Office 以前的项目中用到一点Word简单处理的功能(文字替换和转PDF格式),当时使用的是一套COM组件,必须在服务器上安装office环境.最近考 ...