原题链接:http://poj.org/problem?id=1741

题意:

给你棵树,询问有多少点对,使得这条路径上的权值和小于K

题解:

就。。大约就是树的分治

代码:

#include<iostream>
#include<climits>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdio>
#define MAX_N 10004
using namespace std; struct edge{
public:
int to,length;
edge(int t,int l):to(t),length(l){}
edge(){}
}; int N,K; vector<edge> G[MAX_N]; bool centroid[MAX_N];
int subtree_size[MAX_N]; int ans; int compute_subtree_size(int v,int p){
int c=;
for(int i=;i<G[v].size();i++){
int w=G[v][i].to;
if(w==p||centroid[w])continue;
c+=compute_subtree_size(G[v][i].to,v);
}
subtree_size[v]=c;
return c;
} pair<int,int> search_centroid(int v,int p,int t){
pair<int,int> res=make_pair(INT_MAX,-);
int s=,m=;
for(int i=;i<G[v].size();i++){
int w=G[v][i].to;
if(w==p||centroid[w])continue; res=min(res,search_centroid(w,v,t)); m=max(m,subtree_size[w]);
s+=subtree_size[w];
}
m=max(m,t-s);
res=min(res,make_pair(m,v));
return res;
} void enumeratr_paths(int v,int p,int d,vector<int> &ds){
ds.push_back(d);
for(int i=;i<G[v].size();i++){
int w=G[v][i].to;
if(w==p||centroid[w])continue;
enumeratr_paths(w,v,d+G[v][i].length,ds);
}
} int count_pairs(vector<int> &ds){
int res=;
sort(ds.begin(),ds.end());
int j=ds.size();
for(int i=;i<ds.size();i++){
while(j>&&ds[i]+ds[j-]>K)--j;
res+=j-(j>i?:);
}
return res/;
} void solve_subproblem(int v){
compute_subtree_size(v,-);
int s=search_centroid(v,-,subtree_size[v]).second;
centroid[s]=; for(int i=;i<G[s].size();i++){
if(centroid[G[s][i].to])continue;
solve_subproblem(G[s][i].to);
} vector<int> ds;
ds.push_back();
for(int i=;i<G[s].size();i++){
if(centroid[G[s][i].to])continue; vector<int> tds;
enumeratr_paths(G[s][i].to,s,G[s][i].length,tds); ans-=count_pairs(tds);
ds.insert(ds.end(),tds.begin(),tds.end());
}
ans+=count_pairs(ds);
centroid[s]=false;
} void solve(){
ans=;
solve_subproblem();
printf("%d\n",ans);
} bool input(){
if(scanf("%d%d",&N,&K)!=||N+K==)return false;
for(int i=;i<=N;i++)G[i].clear();
for(int i=;i<N-;i++){
int u,v;
int c;
scanf("%d%d",&u,&v);
scanf("%d",&c);
u--,v--;
G[u].push_back(edge(v,c));
G[v].push_back(edge(u,c));
}
return true;
} int main(){
while(input()){
ans=;
memset(subtree_size,,sizeof(subtree_size));
memset(centroid,,sizeof(centroid));
solve();
}
return ;
}

POJ 1741 Tree 树的分治的更多相关文章

  1. poj 1741 Tree (树的分治)

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

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

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

  3. POJ 1741.Tree 树分治 树形dp 树上点对

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24258   Accepted: 8062 Description ...

  4. POJ 1741 Tree(树的点分治,入门题)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21357   Accepted: 7006 Description ...

  5. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  6. POJ 1741 Tree 树上点分治

    题目链接:http://poj.org/problem?id=1741 题意: 给定一棵包含$n$个点的带边权树,求距离小于等于K的点对数量 题解: 显然,枚举所有点的子树可以获得答案,但是朴素发$O ...

  7. POJ 1741 Tree (点分治)

                                                                        Tree Time Limit: 1000MS   Memory ...

  8. poj 1741 Tree(点分治)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15548   Accepted: 5054 Description ...

  9. poj 1741 Tree(树的点分治)

    poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...

随机推荐

  1. Python 3基础教程7-if语句

    前面文章介绍的循环语句,这里开始介绍控制语句.直接看下面的demo.py例子 # 这里介绍 if语句 x = 5y = 8z = 4s = 5 if x < y: print('x is les ...

  2. UnitOfWork知多少 【转】

    原文链接:https://www.cnblogs.com/sheng-jie/p/7416302.html 1. 引言 Maintains a list of objects affected by ...

  3. cloud.cfg_for_centos

    users: - default disable_root: 0 ssh_pwauth: 1 locale_configfile: /etc/sysconfig/i18n mount_default_ ...

  4. 爬虫:Scrapy16 - Spider Contracts

    Scrapy 通过合同(contract)的方式来提供了测试 spider 的集成方法. 可以硬编码(hardcode)一个样例(sample)url,设置多个条件来测试回调函数处理 response ...

  5. HashMap 的深入学习

    Java为数据结构中的映射定义了一个接口java.util.Map,此接口主要有四个常用的实现类,分别是HashMap.Hashtable.LinkedHashMap和TreeMap,类继承关系如下图 ...

  6. 【bzoj4994】[Usaco2017 Feb]Why Did the Cow Cross the Road III 树状数组

    题目描述 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 样例输入 4 3 2 4 4 1 3 2 1 样例输 ...

  7. 三十道DP练习(持续更新)(pw:DP)

    前言: 话说DP这种纯考思维的题目,总是让我很伤脑筋,一些特别简单的DP我都常常做不出来,所以革命从现在(2018-05-01)开始,努力多刷点DP的练习-. 1.顺序对齐(align) 时间:201 ...

  8. 关于CPU位数,OS位数以及内存大小关系的一点总结

    (这个学期做助教,说来好惭愧啊,虽然我也是考研进来的,但是就在两年前复习的资料居然全部都忘光了.对大二的孩子们提问的问题多半都解决不了!!!越来越觉得自己的学习方法有问题了,总是想着一些知识能够根据自 ...

  9. UltraEdit 删除空行

    UltraEdit 删除空行 数据里有大量的空行,想在UltraEdit里删除,在网上搜了很多方法都不管用,功夫不负有心人,最后终于找到了可用的方法: 搜索—>替换,在“查找什么”里输入:\n( ...

  10. Hibernate中多种方式解除延迟加载

    问题引发:因为dao使用load(),默认延迟加载的,当在biz关闭session之后,UI层无法获取对象的非id属性值 解决方案: 1.变成get,即时加载 2.用Hibernate.isIniti ...