【poj1741】【Tree】

Tree

Time Limit: 1000MS Memory Limit: 30000K

Total Submissions: 13068 Accepted: 4195

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

这道题是楼教主的男人八题

题意是这样的:给你一棵树,让你求出这棵树中的距离<=k的点对的数目。

这是一道点分的模板题,和聪聪可可一样,唯一不同的只是在calc上。

我们考虑我们已经得到了这棵树的子树中的点到重心的距离,那么我们怎样找到距离<=k的点对?

暴力枚举?? 显然会超时。

所以这道题的不同就是我们需要对于所有找到的距离进行排序。

这样我们从左右端点开始向中间找,如果遇到了某一段的左端点和右端点的和<=k,那么说明在这一段中的点都符合,就扩大左端点。

如果发现左端点于右端点的和大于k,就缩小右端点。

这样我们就可以统计出来了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10100;
const int inf=210000000;
int point[N],next[N*4],sum,son[N],n,k,root,f[N],deep[N],ans,dis[N],tot;
struct S{int st,en,va;}aa[N*4];
bool use[N];
inline void add(int x,int y,int z)
{
    tot+=1;next[tot]=point[x];point[x]=tot;
    aa[tot].st=x;aa[tot].en=y;aa[tot].va=z;
    tot+=1;next[tot]=point[y];point[y]=tot;
    aa[tot].st=y;aa[tot].en=x;aa[tot].va=z;
}
/*-------找重心--------*/
inline void get_root(int x,int fa)
{
    int i,u;
    son[x]=1;f[x]=0;
    for(i=point[x];i;i=next[i])
      if(use[aa[i].en]&&aa[i].en!=fa){
        u=aa[i].en;
        get_root(u,x);
        son[x]+=son[u];
        f[x]=max(f[x],son[u]);
      }
    f[x]=max(f[x],sum-son[x]);
    if(f[x]<f[root]) root=x;
}
/*-------计算距离---------*/
inline void get_deep(int x,int fa)
{
    int i;
    deep[0]+=1;
    deep[deep[0]]=dis[x];
    for(i=point[x];i;i=next[i])
      if(use[aa[i].en]&&aa[i].en!=fa){
        dis[aa[i].en]=dis[x]+aa[i].va;
        get_deep(aa[i].en,x);
      }
}
/*---------分治-----------*/
inline int calc(int x,int now)
{
    deep[0]=0;dis[x]=now;
    get_deep(x,0);
    sort(deep+1,deep+deep[0]+1);
    int l=1,r=deep[0],all=0;
    while(l<=r){
        if(deep[l]+deep[r]<=k){
            all+=r-l;
            l+=1;
        }
        else r-=1;
    }
    return all;
}
inline void work(int x)
{
    int i;
    ans+=calc(x,0);
    use[x]=false;
    for(i=point[x];i;i=next[i])
      if(use[aa[i].en]){
        ans-=calc(aa[i].en,aa[i].va);
        root=0;
        sum=son[aa[i].en];
        get_root(aa[i].en,0);
        work(root);
      }
}
int main()
{
    int i,j,x,y,z;
    while(scanf("%d%d",&n,&k)==2){
        if(n==0&&k==0) break;
        tot=root=ans=0;
        memset(son,0,sizeof(son));
        memset(use,1,sizeof(use));
        memset(point,0,sizeof(point));
        memset(next,0,sizeof(next));
        for(i=1;i<n;++i){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        sum=n;f[0]=inf;
        get_root(1,0);
        work(root);
        printf("%d\n",ans);
    }
}
时间: 2024-11-06 03:42:40

【poj1741】【Tree】的相关文章

【Recover Binary Search Tree】cpp

题目: Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing its structure. Note:A solution using O(n) space is pretty straight forward. Could you devise a constant space solution? confused what "{1,#,2,3}&

【Gradient Boosted Decision Tree】林轩田机器学习技术

GBDT之前实习的时候就听说应用很广,现在终于有机会系统的了解一下. 首先对比上节课讲的Random Forest模型,引出AdaBoost-DTree(D) AdaBoost-DTree可以类比AdaBoost-Stump模型,就可以直观理解了 1)每轮都给调整sample的权重 2)获得gt(D,ut) 3)计算gt的投票力度alphat 最后返回一系列gt的线性组合. weighted error这个比较难搞,有没有不用动原来的模型,通过输入数据上做文章就可以达到同样的目的呢? 回想bag

【Validate Binary Search Tree】cpp

题目: Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with

【LeetCode-面试算法经典-Java实现】【107-Binary Tree Level Order Traversal II(二叉树层序遍历II)】

[107-Binary Tree Level Order Traversal II(二叉树层序遍历II)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). For example

【HDOJ 5379】 Mahjong tree

[HDOJ 5379] Mahjong tree 往一颗树上标号 要求同一父亲节点的节点们标号连续 同一子树的节点们标号连续 问一共有几种标法 画了一画 发现标号有二叉树的感觉 初始标号1~n 根结点1可以标1或n 否则其他情况无法让下面的子树满足各自连续并且该根的儿子节点都要连续 根结点下的节点平分其他标号 画一画可以发现 每个根下最多有两颗子树 否则无法满足条件 并且两颗子树占据剩余标号的左右两边 中间夹的必须是叶子 这样才能满足该根下的儿子节点标号连续 若根下只有一颗子树 同样可以选择占剩

【Leetcode】Binary Tree Postorder Traversal

Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recursive solution is trivial, could you do it iteratively? 思路:后序遍历比起先序遍历以及中序遍历要稍微复杂一点,可以考虑用两个stack进行操作,

【POJ 3321】 Apple Tree (dfs重标号设区间+树状数组求和)

[POJ 3321] Apple Tree (dfs重标号设区间+树状数组求和) Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21966   Accepted: 6654 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. K

【leetcode刷题笔记】Validate Binary Search Tree

Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys

【leetcode刷题笔记】Construct Binary Tree from Preorder and Inorder Traversal

Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that duplicates do not exist in the tree. 类似http://www.cnblogs.com/sunshineatnoon/p/3854935.html 只是子树的前序和中序遍历序列分别更新为: //左子树: left_prestart = prestart+1 lef

【Leetcode】Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its level order traversal as: [ [3], [9,20], [15,7] ] 思路:使用