原题链接: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 爬虫-豆瓣读书

    import requests from bs4 import BeautifulSoup def parse_html(num): headers = { 'User-Agent': 'Mozill ...

  2. ASP.NET Core 2.1 源码学习之 Options[3]:IOptionsMonitor 【转】

    原文链接:https://www.cnblogs.com/RainingNight/p/strongly-typed-options-ioptions-monitor-in-asp-net-core. ...

  3. ASP.NET Core [2]:Middleware-请求管道的构成(笔记)

    原文链接:http://www.cnblogs.com/RainingNight/p/middleware-in-asp-net-core.html 中间件处理请求主要分为三个阶段:1. 中间件的注册 ...

  4. install ironic-inspector

    安装相应的包和组件 yum install openstack-ironic-inspector python-ironic-inspector-client -y 创建user openstack ...

  5. win10下乌龟git安装和使用

    一.安装git for windows 首先下载git for windows客户端http://msysgit.github.io/ 安装过程没什么特别的,不停next就ok了     图太多就不继 ...

  6. sharePreference的几个重点

    一.  SharePreferences是用来存储一些简单配置信息的一种机制,使用Map数据结构来存储数据,以键值对的方式存储,采用了XML格式将数据存储到设备中,文件存放在/data/data/&l ...

  7. iOS大神班笔记02-模仿苹果创建单例

    首先我们得要知道苹果是如何实现单例的:1.不能外界调用alloc,一调用就崩掉,其实就是抛异常(类内部第一次调用alloc就不崩溃,其他都崩溃). 2.提供一个方法给外界获取单例.  3.内部创建一次 ...

  8. 2017 多校4 Matching In Multiplication(二分图)

    Matching In Multiplication 题解: 首先如果一个点的度数为1,那么它的匹配方案是固定的,继而我们可以去掉这一对点.通过拓扑我们可以不断去掉所有度数为1的点. 那么剩下的图中左 ...

  9. BZOJ1004 [HNOI2008]Cards 【burnside定理 + 01背包】

    题目链接 BZOJ1004 题解 burnside定理 在\(m\)个置换下本质不同的染色方案数,等于每种置换下不变的方案数的平均数 记\(L\)为本质不同的染色方案数,\(m\)为置换数,\(f(i ...

  10. BZOJ2125 最短路 【仙人掌最短路】

    题目 给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径. 输入格式 输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一 ...