/*
不要低头,不要放弃,不要气馁,不要慌张
题意:
给一棵有n个节点的树,每条边都有一个正权值,求一共有多少个点对使得它们之间路的权值和小于给定的k.
思路:
《分治算法在树的路径问题中的应用》
*/ #include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
#define N 10050
using namespace std;
struct edge{
int id;
long long w;
bool im;
edge *next;
};
struct st{
st(){}
st(int a,long long b,int c){
id=a;dis=b;iid=c;
}
int id,iid;
long long dis;
};
vector<st>mv;
edge edges[N*];
edge *adj[N];
long long ans,kk;
int ednum;
inline void addedge(int a,int b,long long c){
edge *tmp=&edges[ednum++];
tmp->id=b;
tmp->w=c;
tmp->im=;
tmp->next=adj[a];
adj[a]=tmp;
}
int zong,next_val,next;
bool vis[N];
int siz[N],fa[N];
long long dis[N];
void dfs(int pos,int dep){
vis[pos]=;
siz[pos]=;
for(edge *it=adj[pos];it;it=it->next){
if(it->im&&!vis[it->id]){
dfs(it->id,dep+);
siz[pos]+=siz[it->id];
}
}
}
void dfs2(int pos,int dep){
int my_next=-;
vis[pos]=;
for(edge *it=adj[pos];it;it=it->next){
if(it->im&&!vis[it->id]){
my_next=max(my_next,siz[it->id]);
}
}
my_next=max(my_next,zong-siz[pos]);
if(next_val>my_next){
next=pos;
next_val=my_next;
}
for(edge *it=adj[pos];it;it=it->next){
if(it->im&&!vis[it->id]){
dfs2(it->id,dep+);
}
}
}
bool cmp1(st a,st b){
if(a.dis!=b.dis)return a.dis<b.dis;
else return a.iid<b.iid;
}
bool cmp2(st a,st b){
if(a.id!=b.id)return a.id<b.id;
else if(a.dis!=b.dis)return a.dis<b.dis;
else return a.iid<b.iid;
}
inline void del(int a,int b){
for(edge *it=adj[a];it;it=it->next){
if(it->id==b){
it->im=;
return;
}
}
}
void dfs3(int pos,int dep){
vis[pos]=;
if(!dep)dis[pos]=;
for(edge *it=adj[pos];it;it=it->next){
if(it->im&&!vis[it->id]){
if(!dep)fa[it->id]=it->id;
else fa[it->id]=fa[pos];
dis[it->id]=dis[pos]+it->w;
mv.push_back(st(fa[it->id],dis[it->id],it->id));
dfs3(it->id,dep+);
}
}
}
void solve(int pos){
mv.clear();
memset(vis,,sizeof(vis));
dfs(pos,);
zong=siz[pos];
if(zong<=)return;
memset(vis,,sizeof(vis));
next_val=;
dfs2(pos,);
memset(vis,,sizeof(vis));
dfs3(next,);
int n=mv.size();
sort(mv.begin(),mv.end(),cmp1);
for(int i=;i<n;i++){
if(mv[i].dis>kk)break;
ans++;
int l=i+,r=n-;
while(l<=r){
int mid=(l+r)>>;
if(mv[i].dis+mv[mid].dis<=kk)l=mid+;
else r=mid-;
}
ans+=r-i;
}
sort(mv.begin(),mv.end(),cmp2);
int st=;
for(int i=;i<n;i++){
if(mv[i].id!=mv[st].id){
for(int j=st;j<i;j++){
int l=j+,r=i-;
while(l<=r){
int mid=(l+r)>>;
if(mv[j].dis+mv[mid].dis<=kk)l=mid+;
else r=mid-;
}
ans-=r-j;
}
st=i;
}
}
for(int j=st;j<n;j++){
int l=j+,r=n-;
while(l<=r){
int mid=(l+r)>>;
if(mv[j].dis+mv[mid].dis<=kk)l=mid+;
else r=mid-;
}
ans-=r-j;
}
vector<int>mmv;
for(edge *it=adj[next];it;it=it->next){
if(it->im&&siz[it->id]>){
mmv.push_back(it->id);
it->im=;
del(it->id,next);
}
}
for(int i=;i<mmv.size();i++)solve(mmv[i]);
}
int main()
{
int n;
while(scanf("%d%lld",&n,&kk)!=EOF){
ans=;
if(!n)break;
memset(adj,NULL,sizeof(adj));
ednum=;
for(int i=;i<n;i++){
int a,b;
long long c;
scanf("%d%d%lld",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
}
solve();
printf("%lld\n",ans);
}
}

POJ 1741 [点分治][树上路径问题]的更多相关文章

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

                                                                                                 POJ 174 ...

  2. POJ 1741 树分治

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

  3. [八分之三的男人] POJ - 1741 点分治 && 点分治笔记

    题意:给出一棵带边权树,询问有多少点对的距离小于等于\(k\) 本题解参考lyd的算法竞赛进阶指南,讲解的十分清晰,比网上那些讲的乱七八糟的好多了 不过写起来还是困难重重(史诗巨作 打完多校更详细做法 ...

  4. POJ 1741 点分治

    方法:指针扫描数组 每次选择树的重心作为树根,从树根出发进行一次DFS,求出点到树根的距离,把节点按照与树根的的距离放进数组d,设置两个指针L,R分别从前.后开始扫描,每次满足条件时答案累加R-L., ...

  5. 【POJ 1741】 Tree (树的点分治)

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

  6. poj 1741 楼教主男人八题之中的一个:树分治

    http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...

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

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

  8. 点分治——POJ 1741

    写的第一道点分治的题目,权当认识点分治了. 点分治,就是对每条过某个点的路径进行考虑,若路径不经过此点,则可以对其子树进行考虑. 具体可以看menci的blog:点分治 来看一道例题:POJ 1741 ...

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

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

随机推荐

  1. python 抓取百度音乐

    # coding:utf-8 import urllib2 import re import urllib import chardet from json import * category = ' ...

  2. DOCTYPE声明的作用是什么?严格模式与混杂模式如何区分?

    HTML语言已经存在太久了,目前必然会有一些不同版本的文档存在,为了能够让浏览器清楚你的文档的版本类型和风格,需要在文档的起始用DOCTYPE声明制定当前文档的版本和风格.如果在网页中提供了版本信息, ...

  3. CSS背景色渐变

      试了下 渐变色  ,主要确定开始位置  结束位置,以及对应的color-stop;  以下是兼容不同浏览器的代码片段       代码:<style type="text/css& ...

  4. html画布

    一.<canvas>标签 Html5 引入了一个新的<canvas> 标签,这个标签所代表的区域就好象一块画布,你的所有图形绘制最后都要在这块画布上呈现.有了这个标签,浏览器的 ...

  5. Android学习

    http://www.jikexueyuan.com/path/android 一.概述: 03年10月建立android科技,05年8月被google收购,07年11月成立开放手持设备联盟(Open ...

  6. 转~~~ DIV+CSS实现三角形提示框

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel= ...

  7. [课程设计]Scrum 1.3 多鱼点餐系统开发进度

    [课程设计]Scrum 1.3 多鱼点餐系统开发进度   Scrum 1.3 多鱼点餐系统开发进度 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追 ...

  8. MYSQL file types redo log

    https://blogs.oracle.com/mysqlinnodb/entry/data_organization_in_innodb https://blogs.oracle.com/mysq ...

  9. python对象

    一: 基本概念 在pyhton中一切皆对象,就像类unix中的一切皆文件一样,恩,一切.把事物当作对象进行处理, 这样自然就成了面向对象的编程了. 所有的 Python 对像都拥有三个特性:身份,类型 ...

  10. golang,liteide设置 windows7(64)

    1.安转go的环境,exe安装包 2.下载liteide27.2.1 3.打开liteide开始开发,在里面添加gopath,无法读取windows里面的gopath设置,不知道什么原因,以管理员运行 ...