做广告:

#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. 14.3.2.1 Transaction Isolation Levels 事务隔离级别

    14.3.2 InnoDB Transaction Model InnoDB 事务模型 14.3.2.1 Transaction Isolation Levels 事务隔离级别 14.3.2.2 au ...

  2. 腾讯文学动作密集 疑为手Q发力移动阅读铺路

        移动互联网的门票之争并未结束,百度收购91无线,阿里投资新浪微博.UC浏览器,网易推易信.云音乐等等,都是互联网巨头争夺移动互联网门票的最佳案例.不过,上述任何巨头都不可忽视腾讯这个“狠角色” ...

  3. Codeforces 358 D. Dima and Hares

    dp[i][0]表示i号兔子先于i-1号兔子喂食,dp[i][1]反过来. 倒着DP D. Dima and Hares time limit per test 2 seconds memory li ...

  4. Detours信息泄漏漏洞

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  5. Java 建立mysql数据库连接的语句

    每次在面试时被问到jdbc的数据路链接过程都卡着,这次不怕了,背会了... 第一个,比较粗糙的 try{   Class.forName("com.mysql.jdbc.Driver&quo ...

  6. poj 2411 Mondriaan's Dream dp

    一个比较简单的状压dp,记录下每个点的状态即可. #include <iostream> #include <cstdio> #include <cstring> ...

  7. ACdream 1114(莫比乌斯反演)

    传送门:Number theory 题意:给n个数,n 和 每个数的范围都是 1---222222,求n个数中互质的对数. 分析:处理出每个数倍数的个数cnt[i],然后进行莫比乌斯反演,只不过这里的 ...

  8. JavaWeb 项目中的绝对路径和相对路径以及问题的解决方式

    近期在做JavaWeb项目,总是出现各种的路径错误,并且发现不同情况下 /  所代表的含义不同,导致在调试路径上浪费了大量时间. 在JavaWeb项目中尽量使用绝对路径  由于使用绝对路径是绝对不会出 ...

  9. configure: error: zlib not installed

    export LDFLAGS="-L/usr/local/zlib/lib" export CPPFLAGS="-I/usr/local/zlib/include&quo ...

  10. codeforces#253 D - Andrey and Problem里的数学知识

    这道题是这种,给主人公一堆事件的成功概率,他仅仅想恰好成功一件. 于是,问题来了,他要选择哪些事件去做,才干使他的想法实现的概率最大. 我的第一个想法是枚举,枚举的话我想到用dfs,但是认为太麻烦. ...