[POJ1741] Tree【树分治 点分治】
传送门:http://poj.org/problem?id=1741
写的第一道树分治题,撒花纪念~
对于每一对点对(i, j),它有三种情况:
① 其中一个是根节点。这种情况比较简单,直接加上就好了。
② 横跨根节点。这种情况是重点。
③ 不是以上两种情况。这时递归下去求解就好了。
那么对于第二种情况该怎么破呢?设根节点为root,那么dist(i, root) + dist(j, root) <= k,且需要i与j在不同的子树里。直接算不同子树的点对(i, j)的个数会麻烦,所以需要一点技巧:符合条件且在不同子树的(i, j)的对数 = 符合条件的对数 - 符合条件且在相同子树的(i, j)的对数,这样就搞定啦!
#include <cstdio>
#include <cstring>
#include <algorithm> const int maxn = 10005; int n, k, t1, t2, t3, ans;
int head[maxn], to[maxn << 1], next[maxn << 1], w[maxn << 1], lb;
int siz[maxn], a[maxn], left, right;
bool book[maxn]; inline void ist(int aa, int ss, int ww) {
to[lb] = ss;
next[lb] = head[aa];
head[aa] = lb;
w[lb] = ww;
++lb;
}
int fnd_zx(int fr, int tot_node, int p, int & rt, int & mn) {
int mx = 0;
for (int j = head[fr]; j != -1; j = next[j]) {
if (!book[to[j]] && to[j] != p) {
fnd_zx(to[j], tot_node, fr, rt, mn);
mx = std::max(mx, siz[to[j]]);
}
}
mx = std::max(mx, tot_node - siz[fr]);
if (mn > mx) {
mn = mx;
rt = fr;
}
}
void get_siz(int fr, int p) {
siz[fr] = 1;
for (int j = head[fr]; j != -1; j = next[j]) {
if (!book[to[j]] && to[j] != p) {
get_siz(to[j], fr);
siz[fr] += siz[to[j]];
}
}
}
void get_data(int r, int p, int ww) {
if (ww > k) {
return;
}
a[right++] = ww;
for (int j = head[r]; j != -1; j = next[j]) {
if (!book[to[j]] && to[j] != p) {
get_data(to[j], r, ww + w[j]);
}
}
}
int get_ans(int l, int r) {
std::sort(a + l, a + r);
int rt = 0;
--r;
while (r > l) {
while (r > l && a[l] + a[r] > k) {
--r;
}
rt += r - l;
++l;
}
return rt;
}
void slove(int fr) {
int root = -666, mn = 2147483647;
get_siz(fr, 0);
fnd_zx(fr, siz[fr], 0, root, mn);
book[root] = true;
for (int j = head[root]; j != -1; j = next[j]) {
if (!book[to[j]]) {
slove(to[j]);
}
}
left = right = 0;
for (int j = head[root]; j != -1; j = next[j]) {
if (!book[to[j]]) {
get_data(to[j], root, w[j]);
ans -= get_ans(left, right);
left = right;
}
}
ans += get_ans(0, right) + right;
book[root] = false;
} int main(void) {
//freopen("in.txt", "r", stdin);
while (scanf("%d%d", &n, &k) && n && k) {
lb = 0;
memset(head, -1, sizeof head);
memset(next, -1, sizeof next);
ans = 0;
for (int i = 1; i < n; ++i) {
scanf("%d%d%d", &t1, &t2, &t3);
ist(t1, t2, t3);
ist(t2, t1, t3);
}
slove(1);
printf("%d\n", ans);
}
return 0;
}
[POJ1741] Tree【树分治 点分治】的更多相关文章
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- 【poj1741】Tree 树的点分治
题目描述 Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...
- hdu 4812 D Tree(树的点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total ...
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- POJ1741(SummerTrainingDay08-G 树的点分治)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 23380 Accepted: 7748 Description ...
- hdu4812-D Tree (树的点分治)
昨天学了下树分治,今天补这道题,还是太不熟练了,写完之后一直超时.后来查出好多错= =比如v,u写倒了,比如+写成了取最值,比如....爆int...查了两个多小时的错..哭...(没想到进首页了 h ...
- 【POJ 1741】 Tree (树的点分治)
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 100 ...
- 树上点对统计poj1741(树的点分治)
给定一棵树,边上有权值,要统计有多少对点路径的权值和<=k 分治算法在树的路径中的应用 这个论文里面有分析. 任意两点的路径,要么过根结点,要么在子树中.如果在子树中,那么只要递归处理就行了. ...
- POJ 1741 Tree(树的点分治,入门题)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006 Description ...
随机推荐
- BloomFilter学习
看大数据面试题,看到BloomFilter,找了篇文章学习一下: http://www.cnblogs.com/heaad/archive/2011/01/02/1924195.html Bloom ...
- Eclipse luna 装不上 veloeclipse
今天在Eclipse中始终无法安装veloeclipse ,报错:Failed to prepare partial IU: [R]com.googlecode.veloeclipse.ui 2.0. ...
- Android - 渠道号(vender)
渠道号(vender) 本文地址: http://blog.csdn.net/caroline_wendy Android的apk公布,须要统计各个渠道(vendor)的激活数.就能够使用vendor ...
- Java线程池的简单使用
最近由于公司的业务需求,需要使用线程池来进行对数据进行处理,所以就简单的学习了一下线程池的东西,刚接触感觉挺难的,不过使用了就不感觉那么难了,还是蛮简单的, package com.yd.sms.jo ...
- int&boolean——Java和C的一点小差别
Java和C的差别非常多.只是预计这一点非常多人都不知道. 今天面试时碰到这么道C语言题 求执行结果 int x = -1; while(!x!=0){ cout<<x<<en ...
- 深度学习笔记之关于总结、展望、参考文献和Deep Learning学习资源(五)
不多说,直接上干货! 十.总结与展望 1)Deep learning总结 深度学习是关于自动学习要建模的数据的潜在(隐含)分布的多层(复杂)表达的算法.换句话来说,深度学习算法自动的提取分类需要的低层 ...
- The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
我这个错误发生于导入项目的时候..我发现主要是jdk版本的问题.切换一下jdk.直接红叉消失就可以了.....jdk版本一致性还是很重要的
- Python爬虫开发【第1篇】【爬虫案例】
案例一:网站模拟登录 # douban.py from selenium import webdriver from selenium.webdriver.common.keys import Key ...
- Tomcat 安装错误
安装tomcat时,遇到"failed to install tomcat6 service check your settings and permissions"的问题 安装时 ...
- RK3288-OTA编译失败解决办法【转】
本文转载自:http://blog.csdn.net/wangxueming/article/details/52448630 在执行make otapackage的时候出现该错误,是由于drmsi ...