求一棵树上是否存在路径长度为K的点对。

POJ 1714求得是路径权值<=K的路径条数,这题只需要更改一下统计路径条数的函数即可,如果最终的路径条数大于零,则说明存在这样的路径。

刚开始我以为只要在分治过程中出现过长度为K的就算是找到了,其实不然,因为可能是相同子树里面的两个结点,这个结果显然是错误的。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
struct node {
int v, l;
node() {};
node(int _v, int _l):v(_v), l(_l) {};
};
#define N 10015
int n, m, K, size, root, s[N], f[N], d[N], ans;
bool done[N], ok;
vector<int> dep;
vector<node> g[N]; void getroot(int now, int fa) {
int u;
s[now] = 1; f[now] = 0;
for (int i=0; i<g[now].size(); i++)
if ((u = g[now][i].v) != fa && !done[u]) {
getroot(u, now);
s[now] += s[u];
f[now] = max(f[now], s[u]);
}
f[now] = max(f[now], size-s[now]);
if (f[now] < f[root]) root = now;
}
void getdep(int now, int fa) {
dep.push_back(d[now]);
int u; s[now] = 1;
for (int i=0; i<g[now].size(); i++)
if ((u = g[now][i].v) != fa && !done[u]) {
d[u] = d[now] + g[now][i].l;
getdep(u, now);
s[now] += s[u];
}
}
int calc(int now, int init) {
d[now] = init; dep.clear();
getdep(now, 0);
sort(dep.begin(), dep.end());
int ret = 0;
for (int l=0, r=dep.size()-1; l<r; ) {
if (dep[l] + dep[r] == K) {
if (dep[l] == dep[r]) {
ret += (r-l+1)*(r-l)/2; break;
}
int i=l, j=r;
while (dep[i] == dep[l]) i++;
while (dep[j] == dep[r]) j--;
ret += (i-l)*(r-j);
l = i, r = j;
} else if (dep[l] + dep[r] < K) l++;
else r--;
}
return ret;
}
void work(int now) {
ans += calc(now, 0);
int u;
done[now] = true;
for (int i=0; i<g[now].size(); i++)
if (!done[u = g[now][i].v]) {
ans -= calc(u, g[now][i].l);
f[0] = size = s[u];
getroot(u, root=0);
work(root);
}
}
void solve() {
memset(done, false, sizeof(done));
f[0] = size = n;
getroot(1, root=0);
ans = 0;
work(root);
puts(ans ? "AYE" : "NAY");
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
while (scanf("%d", &n) == 1 && n) {
for (int i=0; i<=n; i++) g[i].clear();
int a, b;
for (int i=1; i<=n; i++) {
while (scanf("%d", &a) && a) {
scanf("%d", &b);
g[i].push_back(node(a, b));
g[a].push_back(node(i, b));
}
}
while (scanf("%d", &K) == 1 && K) solve();
puts(".");
} return 0;
}

POJ 2114 Boatherds【Tree,点分治】的更多相关文章

  1. poj 2114 Boatherds (树分治)

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

  2. poj 2114 Boatherds 树的分治

    还是利用点的分治的办法来做,统计的办法不一样了,我的做法是排序并且标记每个点属于哪颗子树. #include <iostream> #include <cstdio> #inc ...

  3. Poj 2114 Boatherds(点分治)

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

  4. POJ 2114 Boatherds 树分治

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

  5. POJ 2114 - Boatherds

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

  6. POJ 2114 Boatherds 划分树

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

  7. poj 1741 树的点分治(入门)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 18205   Accepted: 5951 Description ...

  8. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  9. POJ - 3321 Apple Tree (线段树 + 建树 + 思维转换)

    id=10486" target="_blank" style="color:blue; text-decoration:none">POJ - ...

随机推荐

  1. javacript中的mvc设计模式

    以下内容为原创翻译,翻译不对的地方还请原谅,凑合着看吧. 原文网址是: 来源:http://www.alexatnet.com/articles/model-view-controller-mvc-j ...

  2. C#WinForm中在dataGridView中添加中文表头

    第一步: 注意事项:(1)如果使用数据库,那么第三步的名称可以是任意的,但是不能和数据库中的列名一样,否则会报错:    (2)第四步的页眉文本就是你想用的中文列名,自己定: (3)第六步尤其重要,不 ...

  3. p1205单词翻转-递归解决

    题目描述 Description 给出一个英语句子,希望你把句子里的单词顺序都翻转过来 输入描述 Input Description 输入包括一个英语句子. 输出描述 Output Descripti ...

  4. 2432: [Noi2011]兔农 - BZOJ

    Description 农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到隔壁的小朋友在讨论兔子繁殖的问题. 问题是这样的:第一个月初有一对刚出生的小兔子,经过两个月长大后,这对兔子从第三个月 ...

  5. 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  6. JQuery,UIbootstrap风格弹出层

    <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> <met ...

  7. 【BZOJ】【2819】NIM

    这题……咋说捏,其实是一道披着博弈论外衣的树上操作问题…… 随便用dfs序或者树链剖分转成序列,然后查询路径上的所有点的NIM和(异或和)就行了,毕竟除了是在树上以外,就是裸的NIM问题. 树链剖分: ...

  8. git如何ignore

    今天新建了一个项目传到git上,但是每次编译都会有一些无用的文件生成,于是就编写了ignore.但是发现无用.因为你的文件已经上传到服务器了,再编写ignore就无用了,ignore的适用是文件没上传 ...

  9. VS2010 创建WindowsService服务

    1.新建一个Windows 服务 2.添加Installer 这一步很重要,在处理完你的业务逻辑后需要添加一个Installer才能是你的Windows服务被安装. 在VS中添加Installer 右 ...

  10. prim求MST

    PRIM==>>MST模板 #include <iostream> using namespace std; #define typec int #define V 3 con ...