zoukankan      html  css  js  c++  java
  • BZOJ1468:Tree(点分治)

    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

    Solution

    点分治模板

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define N (40000+10)
     6 using namespace std;
     7 struct node
     8 {
     9     int to,next,len;
    10 }edge[N*2];
    11 int n,k,sum,root,ans;
    12 int head[N],num_edge;
    13 int depth[N],d[N],size[N],maxn[N];
    14 bool vis[N];
    15 void add(int u,int v,int l)
    16 {
    17     edge[++num_edge].to=v;
    18     edge[num_edge].len=l;
    19     edge[num_edge].next=head[u];
    20     head[u]=num_edge;
    21 }
    22 
    23 void Get_root(int x,int fa)
    24 {
    25     size[x]=1; maxn[x]=0;
    26     for (int i=head[x];i!=0;i=edge[i].next)
    27         if (edge[i].to!=fa && !vis[edge[i].to])
    28         {
    29             Get_root(edge[i].to,x);
    30             size[x]+=size[edge[i].to];
    31             maxn[x]=max(maxn[x],size[edge[i].to]);
    32         }
    33     maxn[x]=max(maxn[x],sum-size[x]);
    34     if (maxn[x]<maxn[root]) root=x;
    35 }
    36 
    37 void Get_depth(int x,int fa)
    38 {
    39     depth[++depth[0]]=d[x];
    40     for (int i=head[x];i!=0;i=edge[i].next)
    41         if (edge[i].to!=fa && !vis[edge[i].to])
    42         {
    43             d[edge[i].to]=d[x]+edge[i].len;
    44             Get_depth(edge[i].to,x);
    45         }
    46 }
    47 
    48 int Calc(int x,int cost)
    49 {
    50     d[x]=cost; depth[0]=0;
    51     Get_depth(x,0);
    52     sort(depth+1,depth+depth[0]+1);
    53     int l=1,r=depth[0],cnt=0;
    54     while (l<r)
    55         if (depth[l]+depth[r]<=k)
    56             cnt+=r-l,l++;
    57         else
    58             r--;
    59     return cnt;
    60 }
    61 
    62 void Solve(int x)
    63 {
    64     ans+=Calc(x,0);
    65     vis[x]=true;
    66     for (int i=head[x];i!=0;i=edge[i].next)
    67         if (!vis[edge[i].to])
    68         {
    69             ans-=Calc(edge[i].to,edge[i].len);
    70             sum=size[edge[i].to];
    71             root=0;
    72             Get_root(edge[i].to,0);
    73             Solve(root);
    74         }
    75 }
    76 
    77 int main()
    78 {
    79     int u,v,l;
    80     scanf("%d",&n);
    81     sum=maxn[0]=n;
    82     for (int i=1;i<=n-1;++i)
    83     {
    84         scanf("%d%d%d",&u,&v,&l);
    85         add(u,v,l); add(v,u,l);
    86     }
    87     scanf("%d",&k);
    88     Get_root(1,0);
    89     Solve(root);
    90     printf("%d",ans);
    91 }
  • 相关阅读:
    240个jQuery插件
    MySQL的mysqldump工具导入导出数据库
    [js脚本实现]图片向上滚动并且有停顿的特效
    linux 下常用查看Apache状态语句
    小命令说明
    Linux下Tomcat的启动、关闭、杀死进程
    POJ 数学题目
    2013421 心灵感悟
    证书创建工具 (Makecert.exe)
    有的句子不长,却能鼓舞我们,成为我们坚持下去的动力
  • 原文地址:https://www.cnblogs.com/refun/p/8684110.html
Copyright © 2011-2022 走看看