还是利用点的分治的办法来做,统计的办法不一样了,我的做法是排序并且标记每个点属于哪颗子树。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e4+9;
int head[maxn],lon,n,mm,m;
struct
{
int next,to,w;
}e[maxn<<1];
void edgeini()
{
memset(head,-1,sizeof(head));
lon=0;
}
void edgemake(int from,int to,int w)
{
e[++lon].to=to;
e[lon].w=w;
e[lon].next=head[from];
head[from]=lon;
} int son[maxn],maxson[maxn];
bool use[maxn];
int dp(int t,int from)
{
int ans,tmp,now=1e4+9;
son[t]=maxson[t]=0;
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(u==from||use[u]) continue;
tmp=dp(u,t);
if(maxson[tmp]<now)
{
now=maxson[tmp];
ans=tmp;
}
son[t]+=son[u];
maxson[t]=max(son[u],maxson[t]);
}
son[t]++;
maxson[t]=max(maxson[t],mm-son[t]);
if(maxson[t]<now) ans=t;
return ans;
}
int d[maxn],top;
struct D
{
int data,ss;
bool operator <(const D & xx) const
{
return data<xx.data;
}
}a[maxn];
void dfs(int t,int from)
{
a[++top].data=d[t];
son[t]=0;
for(int k=head[t];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(u==from||use[u]) continue;
d[u]=d[t]+e[k].w;
dfs(u,t);
son[t]+=son[u];
}
son[t]++;
} int ss[maxn];
int cal(int l,int r)
{
int ret=0;
for(;l<r;)
{
while(r>l&&a[l].data+a[r].data>m) r--;
while(r>l&&a[l].data+a[r].data<m) l++;
if(a[l].data+a[r].data==m)
{
int ll=a[l].ss,rr=a[r].ss;
if(ll!=rr) return true;
while(l<r&&a[l+1].data==a[l].data)
{
if(a[l+1].ss!=ll) return true;
l++;
}
while(l<r&&a[r-1].data==a[r].data)
{
if(a[r-1].ss!=rr) return true;
r--;
}
l++;
r--;
}
}
return false;
} bool solve(int t)
{
int now=dp(t,0);
use[now]=1;
d[now]=top=0;
dfs(now,0);
int tmp=2,con=0;
for(int k=head[now];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(use[u]) continue;
con++;
for(int i=tmp;i<tmp+son[u];i++)
a[i].ss=con;
tmp+=son[u];
}
sort(a+1,a+tmp);
a[1].ss=0;
int ret=cal(1,tmp-1);
if(ret) return true;
for(int k=head[now];k!=-1;k=e[k].next)
{
int u=e[k].to;
if(use[u]) continue;
mm=son[u];
if(solve(u)) return true;
}
return false;
} int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d", &n)!=EOF&& n)
{
edgeini();
for(int i=1,to,w;i<=n;i++)
{
while(scanf("%d",&to),to)
{
scanf("%d",&w);
edgemake(i,to,w);
edgemake(to,i,w);
}
}
int tmp;
while(scanf("%d",&tmp)!=EOF&&tmp)
{
m=tmp;
mm=n;
memset(use,0,sizeof(use));
if(solve(1))
printf("AYE\n");
else
printf("NAY\n");
}
printf(".\n");
}
return 0;
}

poj 2114 Boatherds 树的分治的更多相关文章

  1. POJ 2114 Boatherds 树分治

    Boatherds     Description Boatherds Inc. is a sailing company operating in the country of Trabantust ...

  2. POJ 1741 Tree 树的分治

    原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...

  3. poj 2114 Boatherds (树分治)

    链接:http://poj.org/problem?id=2114 题意: 求树上距离为k的点对数量: 思路: 点分治.. 实现代码: #include<iostream> #includ ...

  4. POJ 2114 Boatherds【Tree,点分治】

    求一棵树上是否存在路径长度为K的点对. POJ 1714求得是路径权值<=K的路径条数,这题只需要更改一下统计路径条数的函数即可,如果最终的路径条数大于零,则说明存在这样的路径. 刚开始我以为只 ...

  5. Poj 2114 Boatherds(点分治)

    Boatherds Time Limit: 2000MS Memory Limit: 65536K Description Boatherds Inc. is a sailing company op ...

  6. POJ 2114 Boatherds 划分树

    标题效果:鉴于一棵树,问有两点之间没有距离是k的. 数据的多组 思维:和IOI2011的Race喜欢.不是这么简单.阅读恶心,我是在主要功能的别人的在线副本. CODE: #include <c ...

  7. POJ 2114 - Boatherds

    原题地址:http://poj.org/problem?id=2114 题目大意: 给定一棵点数为\(n~(n \le 10000)\)的无根树,路径上有权值,给出m组询问($m \le 100$), ...

  8. POJ 1741 Tree 树的分治(点分治)

    题目大意:给出一颗无根树和每条边的权值,求出树上两个点之间距离<=k的点的对数. 思路:树的点分治.利用递归和求树的重心来解决这类问题.由于满足题意的点对一共仅仅有两种: 1.在以该节点的子树中 ...

  9. poj 1741 Tree (树的分治)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 30928   Accepted: 10351 Descriptio ...

随机推荐

  1. HDU 1089 A+B for Input-Output Practice (I)

    #include <cstdio> int main() { int a,b; while(scanf("%d%d",&a,&b)!=EOF) prin ...

  2. [置顶] c++播放Flash文件

    最近由于需要在程序中使用Flash播放,所以学习了下如何播放Flash,这里使用atl库中的CAxWindow来处理我们要播放的Flash!由于Flash的很多接口我们都不知道,所以可以参考前一篇文章 ...

  3. 彻底解决:Keil编译提示“File has been changed outside the editor, reload?”提示!

    如图所示,很多同学在使用keil时都可能会碰到上图中的“File has been changed outside the editor, reload?”提示,很令人烦心.当遇到此提示,首先不要郁闷 ...

  4. HTTP协议是无状态协议,怎么理解?

     Http是一个无状态协议,同一个会话的连续两个请求互相不了解,他们由最新实例化的环境进行解析,除了应用本身可能已经存储在全局对象中的全部信息外,该环境不保存与会话有关的不论什么信息. 自己的理解,在 ...

  5. Android GPS应用:动态获取位置信息

    在上文中,介绍了GPS概念及Android开发GPS应用涉及到的常用类和方法.在本文中,开发一个小应用,实时获取定位信息,包括用户所在的纬度.经度.高度.方向.移动速度等.代码如下: Activity ...

  6. Andriod之Activity

    eclipse还原默认的面板设计:Window > Reset Perspective> OK1\ 1.多个Activity之间的关系: 2.Intent的基本作用: 3.在一个Activ ...

  7. js 效果样式大全

    设置 滑动图片背景模糊度 <style type='text/css'>/*透明20%*/.opacity-20 {filter:alpha(opacity=20); /*支持IE浏览器的 ...

  8. 二十三种设计模式及其python实现

    本文源码寄方于github:https://github.com/w392807287/Design_pattern_of_python 参考文献: <大话设计模式>——吴强 <Py ...

  9. Struts2详解

     struts2框架是SSH框架集中的框架之一,是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器层(Controller)来建立 ...

  10. [Python]小笔记-queue

    queue的作用: 队列最大的作用就是先进先出(First in First Out).队列对于解决最短路的时候特别好用. python 2.7: 要使用队列,那么要加载头文件Queue,也就是imp ...