zoukankan      html  css  js  c++  java
  • bzoj1468 Tree

    最经典的点分治题目,在递归子树的时候减去在算父亲时的不合法方案。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 #include<algorithm>
     6 #include<cmath>
     7 #define ll long long
     8 #define N 40005
     9 using namespace std;
    10 struct Node{
    11   int to,next,v;
    12 }e[N<<1];
    13 int sum,rt,n,k,head[N],tot,cnt,mx[N],sz[N],tmp[N],ans;
    14 bool vis[N];
    15 void add(int x,int y,int z){
    16   e[++tot]=(Node){y,head[x],z};head[x]=tot;
    17   e[++tot]=(Node){x,head[y],z};head[y]=tot; 
    18 }
    19 void getroot(int x,int fa){
    20   mx[x]=0;sz[x]=1;
    21   for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa&&!vis[e[i].to]){
    22     getroot(e[i].to,x);
    23     sz[x]+=sz[e[i].to];
    24     mx[x]=max(mx[x],sz[e[i].to]);
    25   }mx[x]=max(mx[x],sum-sz[x]);
    26   if(mx[x]<mx[rt])rt=x;
    27 }
    28 void getdis(int x,int fa,int d){
    29   tmp[++cnt]=d;
    30   for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa&&!vis[e[i].to]){
    31     getdis(e[i].to,x,d+e[i].v);
    32   }
    33 }
    34 void calc(int x,int dis,int type){
    35   cnt=0;
    36   getdis(x,0,0);
    37   sort(tmp+1,tmp+1+cnt);
    38   int l=1,r=cnt;
    39   while(l<=r){
    40     while(tmp[l]+tmp[r]>dis)r--;
    41     if(l>r)break;
    42     ans+=(r-l)*type;l++;
    43   }
    44 }
    45 void work(int x){
    46   vis[x]=1;
    47   calc(x,k,1);
    48   for(int i=head[x];i;i=e[i].next)if(!vis[e[i].to]){
    49     calc(e[i].to,k-e[i].v*2,-1);
    50     sum=sz[e[i].to];rt=0;
    51     getroot(e[i].to,0);
    52     work(rt);
    53   }
    54 }
    55 int main(){
    56 //  freopen("test.in","r",stdin);
    57   scanf("%d",&n); 
    58   for(int i=1;i<n;i++){
    59     int x,y,z;scanf("%d%d%d",&x,&y,&z);
    60     add(x,y,z);
    61   }
    62   scanf("%d",&k);
    63   sum=mx[0]=n;rt=0;ans=0;
    64   getroot(1,0);
    65   work(rt);
    66   printf("%d
    ",ans);
    67 }
    View Code

    1468: Tree

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1099  Solved: 581
    [Submit][Status][Discuss]

    Description

    给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K

    Input

    N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k

    Output

    一行,有多少对点之间的距离小于等于k

    Sample Input

    7
    1 6 13
    6 3 9
    3 5 7
    4 1 3
    2 4 20
    4 7 2
    10

    Sample Output

    5
  • 相关阅读:
    Material Design系列第八篇——Creating Lists and Cards
    Androidの解决自动旋转导致activity重启问题
    cnBlogs博客推荐
    yii中sphinx,Ajax搜索分页
    yii框架中应用jquery表单验证插件
    百度一键分享
    yii框架中邮箱激活(数字签名)
    yii框架中保存第三方登录信息
    yii添加行的增删改查
    yii遍历行下的每列数据(小1月考)
  • 原文地址:https://www.cnblogs.com/wjyi/p/5615991.html
Copyright © 2011-2022 走看看