Description

Give a tree with n vertices,each edge has a length(positive integer less than 1001).
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 input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.

The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0

Sample Output

8
题解
求树上总共有多少点对(u,v)距离<=k
题意
初学点分治
树的重心定义:找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡
点分治就是把树按子树重心不断DFS,然后处理每个子树对答案的贡献,会用到容斥,把n^2的复杂度优化为nlogn
处理每个子树对答案的贡献,先求出重心到各个点的距离,然后sort一下,然后可以二分出满足<=k的答案
代码
 #include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std; const int maxn=1e4+; vector< pair<int,int> >G[maxn];
int mx[maxn],size[maxn],vis[maxn],dis[maxn],ans,MIN,n,k,num,root;
void dfssize(int u,int fa)
{
size[u]=;
mx[u]=;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i].first;
if(!vis[v]&&v!=fa)
{
dfssize(v,u);
size[u]+=size[v];
mx[u]=max(mx[u],size[v]);
}
}
}
void dfsroot(int r,int u,int fa)//r为子树的根
{
if(size[r]-size[u]>mx[u])//子树的其余节点
mx[u]=size[r]-size[u];
if(mx[u]<MIN)//root为重心
MIN=mx[u],root=u;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i].first;
if(!vis[v]&&v!=fa)
dfsroot(r,v,u);
}
}
void dfsdis(int u,int fa,int d)
{
dis[num++]=d;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i].first;
int w=G[u][i].second;
if(!vis[v]&&v!=fa)
dfsdis(v,u,d+w);
}
}
int cal(int r,int w)
{
int ret=;
num=;
dfsdis(r,r,w);
sort(dis,dis+num);
int L=,R=num-;
while(L<R)
{
while(dis[L]+dis[R]>k&&L<R)R--;
ret+=R-L;
L++;
}
return ret;
}
void dfs(int u)
{
MIN=n;
dfssize(u,u);
dfsroot(u,u,u);
int Grivate=root;
ans+=cal(Grivate,);
vis[root]=;
for(int i=;i<G[Grivate].size();i++)
{
int v=G[Grivate][i].first;
int w=G[Grivate][i].second;
if(!vis[v])
{
ans-=cal(v,w);
dfs(v);
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF,n||k)
{
ans=;
for(int i=;i<=n;i++)
{
G[i].clear();
vis[i]=;
}
for(int i=,u,v,w;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
G[u].push_back({v,w});
G[v].push_back({u,w});
}
dfs();
printf("%d\n",ans);
}
return ;
}

POJ 1741 Tree(点分治点对<=k)的更多相关文章

  1. POJ 1741 Tree 求树上路径小于k的点对个数)

                                                                                                 POJ 174 ...

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

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

  3. POJ 1741 Tree 树分治

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

  4. [bzoj 1468][poj 1741]Tree [点分治]

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  5. POJ 1741 Tree ——点分治

    [题目分析] 这貌似是做过第三道以Tree命名的题目了. 听说树分治的代码都很长,一直吓得不敢写,有生之年终于切掉这题. 点分治模板题目.自己YY了好久才写出来. 然后1A了,开心o(* ̄▽ ̄*)ブ ...

  6. [poj 1741]Tree 点分治

    题意 求树上距离不超过k的点对数,边权<=1000 题解     点分治.     点分治的思想就是取一个树的重心,这种路径只有两种情况,就是经过和不经过这个重心,如果不经过重心就把树剖开递归处 ...

  7. POJ - 1741 - Tree - 点分治 模板

    POJ-1741 题意: 对于带权的一棵树,求树中距离不超过k的点的对数. 思路: 点分治的裸题. 将这棵树分成很多小的树,分治求解. #include <algorithm> #incl ...

  8. POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量

    POJ 1741. Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 34141   Accepted: 11420 ...

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

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

随机推荐

  1. wikipedia 维基百科 语料 获取 与 提取 处理 by python3.5

    英文维基百科 https://dumps.wikimedia.org/enwiki/ 中文维基百科 https://dumps.wikimedia.org/zhwiki/ 全部语言的列表 https: ...

  2. redis hset hmset过期时间

    hmset m k v > hset m k v (integer) > hget m k "v" > expire m (integer) > ttl m ...

  3. 游戏数据分析中“次日留存率”与“游戏生命周期第N天上线率”的SAS实现

    在游戏行业,次日留存率是个很重要的指标,对于评价一款游戏的优劣具有很重要的参考价值. 下面先看以下相关的定义: 用户留存:统计时间区间内,新登用户在随后不同时期的登录使用情况. 日次留存率:日新登用户 ...

  4. nginx配置http强制跳转https

    nginx配置http强制跳转https 网站添加了https证书后,当http方式访问网站时就会报404错误,所以需要做http到https的强制跳转设置. 一.采用nginx的rewrite方法 ...

  5. 自己遇到的ajax调用ashx文件无法获取返回值的一种情况

    无法获取返回值的ashx文件大致如下: public void ProcessRequest (HttpContext context) { context.Response.ContentType ...

  6. sql server 2016 附加 其它目录的数据库

    如果数据库不在默认目录,那么需要将 mdf所在目录或者 mdf文件 添加 用户 [NT SERVICE\MSSQLSERVER]的创建权限,否则会提示没有权限, 具体详见: https://docs. ...

  7. jsp 进度条

    <html>  <head>  <title>进度条</title>  <style type="text/css">  ...

  8. solr6.4.1搜索引擎(2)首次同步mysql数据库

    尚未成功启动solr的,请参考我的另一篇文章:http://www.cnblogs.com/zhuwenjoyce/p/6506359.html(solr6.4.1 搜索引擎启动eclipse启动) ...

  9. mysqli用户权限操作

    此操作指令在 mysql 的数据库中 所以要 use mysql 查询mysqli中所有用户的权限 select host,user form user;  添加用户 grant all privil ...

  10. hash 在 perl 中的用法(转载)

    Perl的数据结构中最有趣的一个特性是哈希(hash),它使得在数据片段之间建立键-值(key-value)关联成为可能.虽然这些哈希要远远比普通系统中以数字索引的数组用途更广,但是往往也会使初学者不 ...