poj 1741 树的点分治(入门)
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 18205 | Accepted: 5951 |
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
/*
poj 1741 树的点分治(入门) problem:
给一棵边带权树,问两点之间的距离小于等于K的点对有多少个 solve:
随便找的博客学习下
大致思路,对当前树先求其重心为根节点,然后找出所有点到根节点的距离. 然后就能计算出有多少的的和
<= k. 但是这两个点有可能来自同一个子树,所以在后面计算中减去,就能计算出过当前根节点的所有对.
以同样的方法计算子树的情况,递推下去就行.
重心是为了让最大子树的节点数最小,从而增加效率.
(个人理解)
hhh-2016-08-22 20:00:18
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define key_val ch[ch[root][1]][0]
#define inf 0x3FFFFFFFFFFFFFFFLL
using namespace std;
const int maxn = 100010; struct node
{
int to,w;
node() {};
node(int v,int _w):to(v),w(_w) {};
}; vector<node> q[maxn];
int n,k,s[maxn],f[maxn],root,d[maxn],ans,limit;
int Size;
bool vis[maxn];
vector<int> ta; void get_root(int now,int fa)
{
int v;
s[now] = 1,f[now] = 0;
for(int i = 0;i < q[now].size();i++)
{
if( (v=q[now][i].to) == fa || vis[v])
continue;
get_root(v,now);
s[now] += s[v];
f[now] = max(f[now],s[v]);
}
f[now] = max(f[now],Size - s[now]);
if(f[now] < f[root]) root = now;
} void dfs(int now,int fa)
{
int v;
ta.push_back(d[now]);
s[now] = 1;
for(int i = 0;i < q[now].size();i++)
{
if( (v=q[now][i].to) == fa || vis[v])
continue;
d[v] = d[now] + q[now][i].w;
dfs(v,now);
s[now] += s[v];
}
} int cal(int now,int begi)
{
ta.clear(),d[now] = begi;
dfs(now,0);
sort(ta.begin(),ta.end());
int cnt = 0;
for(int l = 0,r=ta.size()-1;l<r;)
{
if(ta[l] + ta[r] <= limit) cnt += (r-l++);
else r --;
}
return cnt;
} void work(int now)
{
int v;
ans += cal(now,0);
vis[now] = 1;
for(int i = 0;i < q[now].size(); i++)
{
if(!vis[v = q[now][i].to])
{
ans -= cal(v,q[now][i].w);
f[0] = Size = s[v];
get_root(v,root = 0);
work(root);
}
}
} int main()
{
while(scanf("%d%d",&n,&limit) == 2)
{
if(!n && !limit)
break;
for(int i = 0;i <= n;i++) q[i].clear();
memset(vis,0,sizeof(vis)); int a,b,c;
for(int i = 1;i < n;i++)
{
scanf("%d%d%d",&a,&b,&c);
q[a].push_back(node(b,c));
q[b].push_back(node(a,c));
}
f[0] = Size = n;
get_root(1,root = 0);
ans = 0;
work(root);
printf("%d\n",ans);
}
return 0;
}
poj 1741 树的点分治(入门)的更多相关文章
- POJ 1741 树的点分治
题目大意: 树上找到有多少条路径的边权值和>=k 这里在树上进行点分治,需要找到重心保证自己的不会出现过于长的链来降低复杂度 #include <cstdio> #include & ...
- POJ 1741 Tree (树的点分治入门)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 16172 Accepted: 5272 Descripti ...
- POJ 1741 树分治
题目链接[http://poj.org/problem?id=1741] 题意: 给出一颗树,然后寻找点对(u,v)&&dis[u][v] < k的对数. 题解: 这是一个很经典 ...
- poj 1741 树的分治
思路:这题我是看 漆子超<分治算法在树的路径问题中的应用>写的. 附代码: #include<iostream> #include<cstring> #includ ...
- POJ 1741 Tree 树上点分治
题目链接:http://poj.org/problem?id=1741 题意: 给定一棵包含$n$个点的带边权树,求距离小于等于K的点对数量 题解: 显然,枚举所有点的子树可以获得答案,但是朴素发$O ...
- POJ 1741 Tree (点分治)
Tree Time Limit: 1000MS Memory ...
- poj 1741 Tree(点分治)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 15548 Accepted: 5054 Description ...
- poj1741_Tree(树的点分治入门题)
题目链接:poj1741_Tree 题意: 给你一颗n个节点的树,每条边有一个值,问有多少点对(u,v),满足u->v的最短路径小于k. 题解: 典型的树的分治,板子题. #include< ...
- POJ 1741 树上 点的 分治
题意就是求树上距离小于等于K的点对有多少个 n2的算法肯定不行,因为1W个点 这就需要分治.可以看09年漆子超的论文 本题用到的是关于点的分治. 一个重要的问题是,为了防止退化,所以每次都要找到树的重 ...
随机推荐
- choose the max from numbers, use scanf and if else (v1:21.9.2017,v2:23.9.2017)
#include<stdio.h> int main(){ int a,b,c,max; printf("请输入一个数值: "); scanf("%d&quo ...
- 搭建java环境——使用Sublime Text 3(windows环境)
实现sublime Text 3对Java编译执行 参考网址:http://tieba.baidu.com/p/2609515186 1.1直接在安装路径下找到*\Packages\Java.subl ...
- thinkphp调试技巧
调试的经验:很多时候程序调试不出来,但是又找不出错误,往往是拼写错误可能是很小的拼写错误,很难看出,或者多了一个空格,比如在配置路由的时候'URL_ROUTER_ON '=true,这样设置就会错误, ...
- LeetCode & Q20-Valid Parentheses-Easy
Stack String Description: Given a string containing just the characters '(', ')', '{', '}', '[' and ...
- 分布式版本控制系统Git的安装及使用
Git的安装分为客户端安装和服务端安装,鉴于我平时码代码在windows环境下,因此本文客户端安装直接在windows环境,服务端安装在linux环境下(centos). Git客户端安装 客户端下载 ...
- linux下安装redis和phpredis扩展
一.安装redis 1.下载redis-3.2.3.tar.gz wget http://download.redis.io/releases/redis-3.2.3.tar.gz 2.解压redis ...
- 新概念英语(1-141)Sally's first train ride
Lesson 141 Sally's first train ride 萨莉第一交乘火车旅行 Listen to the tape then answer this question. Why was ...
- GIT入门笔记(1)- Git的基本概念
一.概念和定义 1.git是什么 许多人习惯用复制整个项目目录的方式来保存不同的项目版本,或许还会改名加上备份时间以示区别.这么做唯一的好处就是简单.不过坏处也不少:有时候会混淆所在的工作目录,一旦弄 ...
- 新概念英语(1-45)The boss's letter
新概念英语(1-45)The boss's letter Why can't Pamela type the letter? A:Can you come here a minute, please, ...
- Object.defineProperties()和Object.defineProperty()方法
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...