POJ1741 tree 【点分治】
| Time Limit: 1000MS | Memory Limit: 30000K | |
| Total Submissions: 25286 | Accepted: 8421 |
Description
Define dist(u,v)=The min distance between node u and v.
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
Write a program that will count how many pairs which are valid for a given tree.
Input
The last test case is followed by two zeros.
Output
Sample Input
5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0
Sample Output
8
点分治
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 10005,maxm = 40005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int N,K,vis[maxn],head[maxn],d[maxn],dep[maxn],nedge = 0,F[maxn],Siz[maxn],rt = 0,n,ans;
struct EDGE{int to,w,next;}edge[maxm];
inline void build(int u,int v,int w){
edge[nedge] = (EDGE){v,w,head[u]}; head[u] = nedge++;
edge[nedge] = (EDGE){u,w,head[v]}; head[v] = nedge++;
}
void getRT(int u,int fa){
int to; F[u] = 0; Siz[u] = 1;
Redge(u) if ((to = edge[k].to) != fa && !vis[to]){
getRT(to,u);
Siz[u] += Siz[to];
F[u] = max(F[u],Siz[to]);
}
F[u] = max(F[u],n - Siz[u]);
if (F[u] < F[rt]) rt = u;
}
void getdep(int u,int fa){
dep[++dep[0]] = d[u]; int to;
Redge(u) if (!vis[to = edge[k].to] && to != fa){
d[to] = d[u] + edge[k].w;
getdep(to,u);
}
}
int cal(int u,int D){
d[u] = D; dep[0] = 0;
getdep(u,0);
sort(dep + 1,dep + 1 + dep[0]);
int l = 1,r = dep[0],t = 0;
while (l < r)
if (dep[l] + dep[r] <= K) t += r - l++;
else r--;
return t;
}
void solve(int u){
ans += cal(u,0);
vis[u] = true; int to;
Redge(u) if (!vis[to = edge[k].to]){
ans -= cal(to,edge[k].w);
n = Siz[to]; rt = 0;
getRT(to,rt);
solve(rt);
}
}
int main(){
while (true){
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
int a,b,w; N = RD(); K = RD(); ans = 0; rt = 0; nedge = 0;
if (!N) break;
REP(i,N - 1){
a = RD(); b = RD(); w = RD();
build(a,b,w);
}
n = N; F[0] = INF;
getRT(1,0);
solve(rt);
printf("%d\n",ans);
}
return 0;
}
POJ1741 tree 【点分治】的更多相关文章
- [POJ1741]Tree(点分治)
树分治之点分治入门 所谓点分治,就是对于树针对点的分治处理 首先找出重心以保证时间复杂度 然后递归处理所有子树 对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况 路径过当前根 ...
- [poj1741]Tree(点分治+容斥原理)
题意:求树中点对距离<=k的无序点对个数. 解题关键:树上点分治,这个分治并没有传统分治的合并过程,只是分成各个小问题,并将各个小问题的答案相加即可,也就是每层的复杂度并不在合并的过程,是在每层 ...
- [bzoj1468][poj1741]Tree[点分治]
可以说是点分治第一题,之前那道的点分治只是模模糊糊,做完这道题感觉清楚了很多,点分治可以理解为每次树的重心(这样会把数分为若干棵子树,子树大小为log级别),然后统计包含重心的整个子树的值减去各个子树 ...
- POJ1741 Tree 树分治模板
http://poj.org/problem?id=1741 题意:一棵n个点的树,每条边有距离v,求该树中距离小于等于k的点的对数. dis[y]表示点y到根x的距离,v代表根到子树根的距离 ...
- POJ1741 Tree + BZOJ1468 Tree 【点分治】
POJ1741 Tree + BZOJ1468 Tree Description Give a tree with n vertices,each edge has a length(positive ...
- POJ1741 Tree(树分治——点分治)题解
题意:给一棵树,问你最多能找到几个组合(u,v),使得两点距离不超过k. 思路:点分治,复杂度O(nlogn*logn).看了半天还是有点模糊. 显然,所有满足要求的组合,连接这两个点,他们必然经过他 ...
- [poj1741][tree] (树/点分治)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- POJ1741 Tree(树的点分治基础题)
Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v) ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
随机推荐
- OSG-粒子系统和初步
本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...
- C 基本运算
一 算术运算 C语言一共有34种运算符 包括了常见的加减乘除运算 1. 加法运算+ 除开能做加法运算 还能表示正号: +5, +90 2. 减法运算- 除开能做减法运算 还能表示符号: -10, -2 ...
- (Python爬虫05)完善的爬虫学习大纲
- 【WXS数据类型】RegExp
生成 regexp 对象需要使用 getRegExp函数,注意与JS的使用方法不同( new RegExp(pattern,modifiers);) 原型:getRegExp(pattern, mod ...
- python 终极篇 cookie与session
()cookie与session---------->>>>>>>>>>>>>>>>>>&g ...
- Java学习 · 初识 面向对象深入一
面向对象深入 1.面向对象三大特征 a) 继承 inheritance 子类可以从父类继承属性和方法 子类可以提供自己的属性方法 b) 封装 encapsulation 对外隐藏某些属性和方法 对外公 ...
- LeetCode - 442. Find All Duplicates in an Array - 几种不同思路 - (C++)
题目 题目链接 Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ...
- .Net并行编程 - Reactive Extensions(Rx)并发浅析
关于Reactive Extensions(Rx) 关于Reactive Extensions(Rx),先来看一下来自微软的官方描述: The Reactive Extensions (Rx) is ...
- 欢迎来怼--第七次Scrum会议
一.小组信息 队名:欢迎来怼 小组成员: 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/19 17:05~17:17,总计12min. 地 ...
- c# 两个软件传参
1.socket 传参,类似于小型的服务器和客户端,一端发送,另一端保持监听状态. 2.通过第三方 数据库或者文件.