【POJ1741】Tree 树分而治之 模板略?
做广告:
#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 树分而治之 模板略?的更多相关文章
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- POJ1741 Tree(树分治——点分治)题解
题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...
- Hdu 5274 Dylans loves tree (树链剖分模板)
Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...
- poj 1744 tree 树分治
Tree Time Limit: 1000MS Memory Limit: 30000K Description Give a tree with n vertices,each ed ...
- Tree( 树) 组件[4]
本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一.方法列表 //部分方法onClick : funct ...
- Tree( 树) 组件[3]
本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一. 事件列表很多事件的回调函数都包含'node'参数, ...
- Tree( 树) 组件[2]
本节课重点了解 EasyUI 中 Tree(树)组件的使用方法, 这个组件依赖于 Draggable(拖动)和 Droppable(放置)组件.一. 异步加载如果想从数据库里获取导航内容, 那么就必须 ...
随机推荐
- 在 Ubuntu 12.04 上通过安装源安装 Open vSwitch (OVS)
先把Ubuntu 12.04更新一下 sudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade 删除 Ebtables包 s ...
- HNCU1099:堆积木
http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1099 题目描述 小明的侄子要过生日了,小 ...
- java中Executor、ExecutorService、ThreadPoolExecutor介绍(转)
1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes th ...
- Android笔记二十七.Service组件入门(一).什么是Service?
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.Service 1.Service简单介绍 Service为Android四大组件之中 ...
- 杭州电ACM1098——Ignatius's puzzle
这个话题.简单的数学. 对于函数,f(x)=5*x^13+13*x^5+k*a*x,输入k,对于休闲x,一个数字的存在a,使f(x)是65可分. 对于休闲x. 因此,当x = 1时间,f(x) = 1 ...
- hdu 1251 统计难题 (map水过)
# include <stdio.h> # include <algorithm> # include <string> # include <map> ...
- Java程序猿学习当中各个阶段的建议
回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议 引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的 ...
- 2014年度辛星解读css第四节
接下来的这一节我计划解说的是超链接和列表的样式,然后我们做出一个导航栏出来,事实上导航栏是很常见的,可是我们这里做得这个有点并不那么完好,等我们学完了css之后再完好它. ************** ...
- JAVA Socket(多个客户同时连接,信息共享) client (java/ruby)
第一步 充分理解Socket 1.什么是socket 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字" ...
- IE浏览器审查密码的清除
上周去188工业区,总装厂的喷油部的电脑上被谁设置了IE的审查密码,后来通过电话沟通,运维岗给出了具体的解决方法: 进入注册表HKEY_LOCAL_MACHINE\Software\Microsoft ...