Tree

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
树的点分治 参考了漆子超的论文 以及多位大佬的博客

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<cstdlib>
#include<stack>
#include<string>
#define eps 0.000000001
typedef long long ll;
typedef unsigned long long LL;
using namespace std;
const int INF=0x3f3f3f3f;
const int N=+;
int son[N];
int ans;
int num;
int p;
int head[N];
int vis[N];
int minn;
int root;
int k;
int dis[N];
void init(){
num=;
memset(vis,,sizeof(vis));
memset(head,-,sizeof(head));
}
struct node{
int to,next,w;
}edge[N];
void add(int u,int v,int w){
edge[num].to=v;
edge[num].w=w;
edge[num].next=head[u];
head[u]=num++;
}
void getroot(int x,int y,int n){
son[x]=;
int maxx=;
for(int i=head[x];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==y||vis[v])continue;
getroot(v,x,n);
son[x]=son[x]+son[v];
maxx=max(maxx,son[v]);
}
maxx=max(maxx,n-son[x]);
//cout<<maxx<<" "<<x<<endl;
if(minn>maxx){
minn=maxx;
root=x;
}
}
void getdeep(int x,int v0,int y){
dis[p++]=y;
for(int i=head[x];i!=-;i=edge[i].next){
int v=edge[i].to;
if(v==v0||vis[v])continue;
getdeep(v,x,y+edge[i].w);
}
}
int cal(int x,int y){
int res=;
p=;
getdeep(x,,y);
sort(dis,dis+p);
int l=;
int r=p-;
while(l<r){
if(dis[l]+dis[r]<=k){
res=res+(r-l);
l++;
}
else{
r--;
}
}
return res;
}
void work(int x){
ans=ans+cal(x,);
//cout<<cal(x,0)<<" ";
// cout<<endl;
vis[x]=;
for(int i=head[x];i!=-;i=edge[i].next){
int v=edge[i].to;
if(vis[v]==){
ans=ans-cal(v,edge[i].w);
minn=INF;
getroot(v,,son[v]);
work(root);
}
}
}
int main(){
int n;
while(scanf("%d%d",&n,&k)!=EOF){
if(n==&&k==)break;
init();
for(int i=;i<n-;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
ans=;
minn=INF;
getroot(,-,n);
//for(int i=1;i<=n;i++)cout<<son[i]<<" ";
// cout<<endl;
//cout<<root<<" "<<minn<<endl;
work(root);
cout<<ans<<endl;
}
return ;
}

poj 1741(树的点分治)的更多相关文章

  1. poj 1741 树的点分治(入门)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 18205   Accepted: 5951 Description ...

  2. POJ 1741 树的点分治

    题目大意: 树上找到有多少条路径的边权值和>=k 这里在树上进行点分治,需要找到重心保证自己的不会出现过于长的链来降低复杂度 #include <cstdio> #include & ...

  3. POJ 1741 树分治

    题目链接[http://poj.org/problem?id=1741] 题意: 给出一颗树,然后寻找点对(u,v)&&dis[u][v] < k的对数. 题解: 这是一个很经典 ...

  4. poj 1741 树的分治

    思路:这题我是看 漆子超<分治算法在树的路径问题中的应用>写的. 附代码: #include<iostream> #include<cstring> #includ ...

  5. POJ 1741 Tree 树上点分治

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

  6. POJ 1741 Tree (点分治)

                                                                        Tree Time Limit: 1000MS   Memory ...

  7. poj 1741 Tree(点分治)

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

  8. POJ 1741 树上 点的 分治

    题意就是求树上距离小于等于K的点对有多少个 n2的算法肯定不行,因为1W个点 这就需要分治.可以看09年漆子超的论文 本题用到的是关于点的分治. 一个重要的问题是,为了防止退化,所以每次都要找到树的重 ...

  9. POJ 1741 树上的点分治

    题目大意: 找到树上点对间距离不大于K的点对数 这是一道简单的练习点分治的题,注意的是为了防止点分治时出现最后分治出来一颗子树为一条直线,所以用递归的方法求出最合适的root点 #include &l ...

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

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

随机推荐

  1. js 学习笔记---BOM

    window对象 1. window 对象是Global对象,在全局作用域中声明的变量和函数都可以通过window.来访问.跟直接在window上添加属性效果一样.唯一的区别就是delete时,如果是 ...

  2. Node.js概述

    Node.js最重要的特性:通过单线程实现异步处理环境 Node.js解决的问题: Node.js修改了客户端连接服务器端的连接方法,不需要为每个客户端连接创建一个新的线程,而是为每个客户端连接触发一 ...

  3. ABP生成错误:必须添加对程序集“netstandard”的引用

    当前使用ABP版本为:4.6.0 升级vs2017到15.4版本,升级framework到4.7版本 如果Core版本请升级到net core 2

  4. MIUI 的参与感

    最近这段时间在看小米联合创始人黎万强写的<参与感>这本书,看完我还挺有感触的.小米相信大家都一定有所耳闻. 2010 年 4 月 6 日            小米公司正式创立. 8 月 ...

  5. Django - 一对多跨表操作

    1.views.py 2.host.html 运行结果: 通过外键,来进行多表取值(多表取值包括后台取值及前端获取): 多表获取数据时,可以通过以下几种方式实现: 1.从query  set 中获取某 ...

  6. 2 Button

    // <summary> /// 设置透明按钮样式 /// </summary> private void SetBtnStyle(Button btn) { btn.Flat ...

  7. yum插件

    参考文章: http://www.linuxfly.org/post/297/ [root@dnstest07.tbc /home/ahao.mah] #rpm -qa |grep yum yum-p ...

  8. Luogu P2068 统计和

    P2068 统计和 题目描述 给定一个长度为n(n<=100000),初始值都为0的序列,x(x<=10000)次的修改某些位置上的数字,每次加上一个数,然后提出y (y<=1000 ...

  9. 蓝桥-区间K大数查询

    问题描述: 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. 第二行包含n个正整数,表示给定的序列. 第三个包含一个正整数m,表示询问个 ...

  10. css图片居中(水平居中和垂直居中)

    css图片居中(水平居中和垂直居中) css图片居中分css图片水平居中和垂直居中两种情况,有时候还需要图片同时水平垂直居中,下面分几种居中情况分别介绍. css图片水平居中 利用margin: 0 ...