做广告:

#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. select value from v$diag_info where name='Default Trace File';

    VALUE -------------------------------------------------------------------------------- /u01/diag/rdb ...

  2. Android installed app, never used, cannot receiver BroadcastReceiver

    官方文档是这么写的:(http://developer.android.com/about/versions/android-3.1.html#launchcontrols) Launch contr ...

  3. [Xcode]使用target进行协同开发

    协同开发时候发现难免会因为某些条件宏导致上传到SVN的代码影响到其他同时,但是每一次去修很多条件编译也不是很方便,所以可以通过新建自己的target来控制product. 一.创建自己的target: ...

  4. DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

    DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类) 一.DAO模式简介 DAO即Data Access Object,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据 ...

  5. 1.SQL统计某张表的列数。

    select   count(syscolumns.name)    from   syscolumns   ,   sysobjects       where   syscolumns.id    ...

  6. Linux源文件夹结构呈现

    1.arch文件夹: - 相关的存储在不同平台上的代码,每个平台都采用了不同的文件夹来区分. ******Alpha平台 ******Arm平台 ******Arv32平台 ******X86平台 2 ...

  7. Twitter僵尸帐号厂商雇佣中国员工专填验证码_Web2.0 - Microblogging 微博_cnBeta.COM

    Twitter僵尸帐号厂商雇佣中国员工专填验证码_Web2.0 - Microblogging 微博_cnBeta.COM Twitter僵尸帐号厂商雇佣中国员工专填验证码

  8. undefined reference to `sin&#39;问题解决

    作者:zhanhailiang 日期:2014-10-25 使用gcc编译例如以下代码时报"undefined reference to `sin'": #include < ...

  9. 008实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

    我们维护两个指针, 它们之间的距离为n. 然后.我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变. 那么, 当第二个指针指到空时.第一个指针即为所求. #include <ios ...

  10. LaTeX中表格多行显示的最简单设置方法

    这事实上是一个非常easy的问题,可是这两天发现我之前的解决方式太麻烦了.简介一下这样的最简单的方法: 之前设置多行显示的时候,用类似于以下这样的方法进行多行显示: \begin{table} \ne ...