Tree
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 11570   Accepted: 3626

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

Source

我的点分治第一题~~~

树上的路径分为两类:

经过根结点。不经过根结点。

那么我们能够选择每个点为根,然后计算经过这个根结点的长度<=k的路径,再依照同样的方法计算他的全部子树中的路径条数,这样就能不重不漏。

怎样计算经过根结点且长度<=k的路径条数?

用全部的减去在同一棵子树中的就能够。

怎么计算全部的长度<=k的路径?

用dfs求出每一个点的深度,存在一个数组里。然后从小到大排个序。用两个指针扫:l=1,r=tot,在l添加的过程中满足dep[l]+dep[r]<=k的r指针是不增的,所以O(n)能够出解,再加上sort的O(nlogn)。这个操作的复杂度为O(nlogn)。

所以总的复杂度为O(递归层数*nlogn)。怎样让递归层数最少?

每次让重心(找重心【POJ 1655】)当根结点,递归层数是logn的。

于是总复杂度为O(nlog^2n)~

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#define M 10005
using namespace std;
struct edge
{
int y,ne,l;
}e[M*100];
int ans,all,h[M],f[M],done[M],s[M],dep[M],tot=0,size,n,k,root;
void Addedge(int x,int y,int l)
{
tot++;
e[tot].y=y;
e[tot].ne=h[x];
e[tot].l=l;
h[x]=tot;
}
void Getroot(int x,int fa)
{
f[x]=0;
s[x]=1;
for (int i=h[x];i;i=e[i].ne)
{
int y=e[i].y;
if (y==fa||done[y]) continue;
Getroot(y,x);
s[x]+=s[y];
f[x]=max(f[x],s[y]);
}
f[x]=max(f[x],size-s[x]);
if (f[x]<f[root]) root=x;
}
void Getdep(int x,int fa,int de)
{
dep[++all]=de;
s[x]=1;
for (int i=h[x];i;i=e[i].ne)
{
int y=e[i].y,l=e[i].l;
if (y==fa||done[y]) continue;
Getdep(y,x,de+l);
s[x]+=s[y];
}
}
int calc(int x,int de)
{
int an=0;
all=0;
Getdep(x,0,de);
sort(dep+1,dep+1+all);
for (int l=1,r=all;l<r;)
if (dep[l]+dep[r]<=k) an+=r-l++;
else r--;
return an;
}
void Solve(int x)
{
ans+=calc(x,0);
done[x]=true;
for (int i=h[x];i;i=e[i].ne)
{
int y=e[i].y;
if (done[y]) continue;
ans-=calc(y,e[i].l);
size=f[0]=s[y];
Getroot(y,root=0);
Solve(root);
}
}
int main()
{
while (scanf("%d%d",&n,&k)==2)
{
if (n==k&&n==0) break;
tot=0;
for (int i=1;i<=n;i++)
h[i]=0,done[i]=false;
for (int i=1;i<n;i++)
{
int x,y,l;
scanf("%d%d%d",&x,&y,&l);
Addedge(x,y,l);
Addedge(y,x,l);
}
ans=0;
f[0]=size=n;
Getroot(1,root=0);
Solve(root);
printf("%d\n",ans);
}
return 0;
}

感悟:

1.TLE是由于Solve(root)。写成Solve(y)了。。

2.点分治的关键是要知道路径分经过根结点和不经过根结点,由此找到递归方法。

【POJ 1741】Tree的更多相关文章

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

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

  2. 【POJ 1741】 Tree

    [题目链接] http://poj.org/problem?id=1741 [算法] 点分治 要求距离不超过k的点对个数,不妨将路径分成两类 : 1. 经过根节点 2. 不经过根节点 考虑第1类路径, ...

  3. 【POJ 2486】 Apple Tree(树型dp)

    [POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Acce ...

  4. 【POJ 2750】 Potted Flower(线段树套dp)

    [POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   ...

  5. bzoj 2295: 【POJ Challenge】我爱你啊

    2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec  Memory Limit: 128 MB Description ftiasch是个十分受女生欢迎的同学,所以 ...

  6. 【链表】BZOJ 2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 382  Solved: 111[Submit][S ...

  7. BZOJ2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 284  Solved: 82[Submit][St ...

  8. BZOJ2293: 【POJ Challenge】吉他英雄

    2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 80  Solved: 59[Submit][Stat ...

  9. BZOJ2287: 【POJ Challenge】消失之物

    2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 254  Solved: 140[Submit][S ...

随机推荐

  1. 基于perl面向对象开发的微信机器人

    <pre name="code" class="html">[root@wx03 lib]# ls -ltr total 40 -rw-r--r-- ...

  2. PHP学习之-1.4 计算表达式

    计算表达式 不同于HTML和CSS,在PHP中做计算,比如我们写 echo 12*3 计算结果是36.代码如下 <?php echo 12*3;?> 实例 <!DOCTYPE HTM ...

  3. 九道大型软件公司.net面试题!一定得看(附答案)

    1:a=10,b=15,在不用第三方变量的前提下,把a,b的值互换   2:已知数组int[] max={6,5,2,9,7,4,0};用快速排序算法按降序对其进行排列,并返回数组   3:请简述面向 ...

  4. C++学习之路—继承与派生(二):派生类的构造函数与析构函数

    (根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 由于基类的构造函数和析构函数是不能被继承的,所以 ...

  5. CodeForces 370C. Mittens

    C. Mittens time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  6. OCA读书笔记(2) - 安装Oracle软件

    Objectives: •Describe your role as a database administrator (DBA) and explain typical tasks and tool ...

  7. Android 驱动(二) IIC简单介绍

    一. I2C简单介绍 I2C(Inter-Integrated Circuit)总线是一种由 Philips 公司开发的两线式串行总线,用于连接微控制器及其外围设备.I2C 总线最基本的长处就是简单性 ...

  8. pig对null的处理(实际,对空文本处理为两种取值null或‘’)

    pig对文本null的处理非常特殊.会处理成两种null,还会处理成''这样的空值. 比方,读name,age,sex日志信息.name取值处理,假设记录为".,,"这样,会将na ...

  9. 在VC资源文件中加入声音资源

    本文介绍如何在VC资源文件中加入自己的声音资源,使自己的应用程序可以播放声音. 1.首先用文本编辑器(如记事本)打开资源文件(.rc文件) 在最后加入自己的声音资源,如下IDW WAVE " ...

  10. J2SE学习小结

    开始接触Java的学习,Java 2 Standard Edition为Java2平台的标准版,其包括了构成Java语言核心的类,此番学习算是学习了Java体系中的基础部分. 学习框架大致整理如下: ...