Tree
 
 

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

题意:

  给你一个含有n个节点的树,每条边有权值,问你有多少点对最短路径不超过k

题解:

  树分治入门题

  推荐看09年ioi的论文

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5+, M = 1e2+, mod = 1e9+, inf = 1e9+;
typedef long long ll; int n,m,root,t,ans,allnode,siz[N],K,head[N],vis[N],d[N];
int deep[N];//路径长度//deep[0]子节点个数
int f[N];//重心 struct edg{int to,next,v;}e[N * ];//前向星存边
void add(int u,int v,int w) {e[t].to=v;e[t].next=head[u];e[t].v=w;head[u]=t++;}//加边 //获取重心
void getroot(int x,int fa) {
siz[x] = ;
f[x] = ;
for(int i=head[x];i;i=e[i].next) {
int to = e[i].to;
if(to == fa || vis[to]) continue;
getroot(to,x);
siz[x] += siz[to];
f[x] = max(f[x] , siz[to]);
}
f[x] = max(allnode-siz[x] , f[x]);
if(f[x] < f[root]) root = x;
} void getdeep(int x,int fa) {//获取子树所有节点与根的距离
deep[++deep[]] = d[x];
for(int i=head[x];i;i=e[i].next) {
int to = e[i].to;
if(to == fa || vis[to]) continue;
d[to] = d[x] + e[i].v;
getdeep(to,x);
}
}
int cal(int x,int now) {//计算当前以重心x的子树下,所有情况的答案
d[x]=now;deep[]=;
getdeep(x,);
sort(deep+,deep+deep[]+);
int all = ;
for(int l=,r=deep[];l<r;) {
if(deep[l]+deep[r] <= K) {all += r-l;l++;}
else r--;
}
return all;
} void work(int x) {//以x为重心进行计算
vis[x] = ;
ans+=cal(x,);
for(int i=head[x];i;i=e[i].next) {
int to = e[i].to;
if(vis[to]) continue;
ans -= cal(to,e[i].v);
allnode = siz[to];
root=;
getroot(to,x);
work(root);
}
} int main()
{
while(~scanf("%d%d",&n,&K)) {
if(!n&&!m) break;
memset(head,,sizeof(head));
memset(vis,,sizeof(vis));
t = ;
for(int i=;i<n;i++) {
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c) , add(b,a,c);
}
root=ans=;
allnode=n;f[]=inf;
getroot(,);
work(root);
printf("%d\n",ans);
}
}

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

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

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

  2. poj 1741 Tree (树的分治)

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

  3. poj 1744 tree 树分治

    Tree Time Limit: 1000MS   Memory Limit: 30000K       Description Give a tree with n vertices,each ed ...

  4. POJ 1741 Tree ——点分治

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

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

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

  6. POJ 1741 Tree 树的分治

    原题链接:http://poj.org/problem?id=1741 题意: 给你棵树,询问有多少点对,使得这条路径上的权值和小于K 题解: 就..大约就是树的分治 代码: #include< ...

  7. Tree POJ - 1741【树分治】【一句话说清思路】

    因为该博客的两位作者瞎几把乱吹(" ̄︶ ̄)人( ̄︶ ̄")用彼此的智慧总结出了两条全新的定理(高度复杂度定理.特异根特异树定理),转载请务必说明出处.(逃 Pass:anuonei, ...

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

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

  9. POJ 1741 Tree(点分治点对<=k)

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

随机推荐

  1. 【leetcode】Word Break II

    Word Break II Given a string s and a dictionary of words dict, add spaces in s to construct a senten ...

  2. Debian上安装Apache+Django全过程

    -->start sudo apt-get install apache2 libapache2-mod-wsgi #https://wiki.debian.org/zh_CN/Apache s ...

  3. js 一搬问题汇总

    --有时无法进行js调试,在浏览器中设置启用脚本调试就可以了

  4. C#在类中用调用Form的方法

    class 你的类 { private Form1 frm; //构造函数 public 你的类( Form1 form) { frm = form; } //调用form方法 private voi ...

  5. nyoj133_子序列_离散化_尺取法

    子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:5   描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...

  6. Parallels Destop软件配置

    Parallels Destop个人感觉最好用的mac虚拟win软件 http://pan.baidu.com/s/1jHFwIGm 密码:ab21百度云下载(或者下载自己百度云的) 安装方法: 1. ...

  7. 【linux】jdk安装

    1.在http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下载最新版的rpm文件,我 ...

  8. IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序

    /*******************************快速排序 start**********************************///随即取 当前取第一个,首先找到第一个的位置 ...

  9. IOS- 单例

    单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 1.单例模式的要点: 显然单例模式的要点有三个:一是某个类只能有一个实例: ...

  10. Mysql 数据库无法删除 41 错误

    今天删除Mysql 数据库时候,没法删除,直接报错 41: 方法,进入 mysql的安装目录 我的是:D:\tools\Mysql\V76384-01\mysql-advanced-5.6.25-wi ...