POJ 2114 点分治
思路:
点分治
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 10005
int n,k,xx,yy,first[N],next[N*2],v[N*2],w[N*2],tot;
int f[N],size[N],vis[N],d[N],deep[N],root,sum,ans;
void add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void getroot(int x,int fa){
size[x]=1,f[x]=0;
for(int i=first[x];~i;i=next[i])if(!vis[v[i]]&&v[i]!=fa)
getroot(v[i],x),size[x]+=size[v[i]],f[x]=max(f[x],size[v[i]]);
f[x]=max(f[x],sum-size[x]);
if(f[x]<f[root])root=x;
}
void getdeep(int x,int fa){
deep[++deep[0]]=d[x];
for(int i=first[x];~i;i=next[i])if(v[i]!=fa&&!vis[v[i]]&&d[x]+w[i]<=k)
d[v[i]]=d[x]+w[i],getdeep(v[i],x);
}
int calc(int x,int now){
d[x]=now,deep[0]=0,getdeep(x,0);
sort(deep+1,deep+deep[0]+1);
int t=0,l=1,r=deep[0];
while(l<r)
if(deep[l]+deep[r]<k)l++;
else if(deep[l]+deep[r]>k)r--;
else{
if(deep[l]==deep[r]){t+=(r-l+1)*(r-l)/2;break;}
int st=l,ed=r;
while(deep[st]==deep[l])st++;
while(deep[ed]==deep[r])ed--;
t+=(st-l)*(r-ed);
l=st,r=ed;
}
return t;
}
void work(int x){
ans+=calc(root,0),vis[x]=1;
for(int i=first[x];~i;i=next[i])if(!vis[v[i]])
ans-=calc(v[i],w[i]),
sum=size[v[i]],root=0,
getroot(v[i],x),work(root);
}
int read(){
int x=0;char p=getchar();
while(p<'0'||p>'9')p=getchar();
while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();
return x;
}
int main(){
while(scanf("%d",&n)&&n){
memset(first,-1,sizeof(first));tot=0;
for(int i=1;i<=n;i++)
while(xx=read())
yy=read(),add(i,xx,yy),add(xx,i,yy);
while(k=read()){
memset(vis,0,sizeof(vis));
f[0]=10005,root=ans=0,sum=n,getroot(1,0);
work(root);
puts(ans?"AYE":"NAY");
}puts(".");
}
}
POJ 2114 点分治的更多相关文章
- poj 2114 Boatherds (树分治)
链接:http://poj.org/problem?id=2114 题意: 求树上距离为k的点对数量: 思路: 点分治.. 实现代码: #include<iostream> #includ ...
- POJ 2114 Boatherds【Tree,点分治】
求一棵树上是否存在路径长度为K的点对. POJ 1714求得是路径权值<=K的路径条数,这题只需要更改一下统计路径条数的函数即可,如果最终的路径条数大于零,则说明存在这样的路径. 刚开始我以为只 ...
- poj 2114 Boatherds 树的分治
还是利用点的分治的办法来做,统计的办法不一样了,我的做法是排序并且标记每个点属于哪颗子树. #include <iostream> #include <cstdio> #inc ...
- Poj 2114 Boatherds(点分治)
Boatherds Time Limit: 2000MS Memory Limit: 65536K Description Boatherds Inc. is a sailing company op ...
- POJ 2114 (点分治)
题目:https://vjudge.net/contest/307753#problem/B 题意:求树中路径和=k的点对是否存在 思路:点分治,这个题其实和上一题洛谷一样,只是这个数据强,我们不能直 ...
- 树分治 点分治poj 2114
存在2点间距离==k 输出AYE 否则输出NAY #include<stdio.h> #include<string.h> #include<algorithm> ...
- POJ 2114 Boatherds 树分治
Boatherds Description Boatherds Inc. is a sailing company operating in the country of Trabantust ...
- poj 2114 树的分治 可作模板
/* 啊啊啊啊啊啊啊本题证明一个问题,在实际应用中sort比qsort块 还有memset这类初始化能不加尽量别加,很浪费时间 原来的程序把qsort该成sort,去掉一个无用memset就a了时间不 ...
- POJ 2114 - Boatherds
原题地址:http://poj.org/problem?id=2114 题目大意: 给定一棵点数为\(n~(n \le 10000)\)的无根树,路径上有权值,给出m组询问($m \le 100$), ...
随机推荐
- hdoj--3594--Cactus(tarjan)
Cactus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- 41.使用SAX读取XML
main.cpp #include <QtGui> #include <iostream> #include "saxhandler.h" int main ...
- C++中的pair,make_pair学习
std::pair主要的作用是将两个数据组合成一个数据,两个数据可以是同一类型或者不同类型.例如std::pair<int,float> 或者 std::pair<double,do ...
- P1343 地震逃生
题目描述 汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边.1号点为教室,n号点为安全地带,每条边都只能容纳一定量 ...
- Java NIO(六)选择器
前言 Selector选择器是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样使得一个单独的线程可以管理多个Channel,从而管理多个网络连接.选择 ...
- 用endnote导入bib
首先一般时候需要把IEEE的style包导入. https://endnote.com/downloads/styles/ 具体方法可参考http://muchong.com/html/201006/ ...
- DirectUI界面编程(一)创建第一个应用
1.获取Duilib库文件 通过上一节大家对DirectUI界面设计有了初步的了解,本节开始我们一起学习Duilib界面库的使用. 首先我们需要获取Duilib库,目前最新版本为2.0,最新版本源码托 ...
- easyui easyui-accordion的使用和在tab切换时没有样式
1.easyui-accordion的使用 <div id="aa" class="easyui-accordion" style="width ...
- 算法21----重塑矩阵 LeetCode566
1.题目 在MATLAB中,有一个非常有用的函数 reshape,它可以将一个矩阵重塑为另一个大小不同的新矩阵,但保留其原始数据. 给出一个由二维数组表示的矩阵,以及两个正整数r和c,分别表示想要的重 ...
- HDU 5533 Dancing Stars on Me( 有趣的计算几何 )
链接:传送门 题意:给出 n 个点,判断能不能构成一个正 n 边形,这 n 个点坐标是整数 思路:这道题关键就在与这 n 个点坐标是正整数!!!可以简单的分析,如果 n != 4,那一定就不能构成正 ...