• bzoj 1468 Tree 点分


    Tree

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1972  Solved: 1101
    [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

    HINT

     题解:点分模板题
     1 #include<cstring>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstdio>
     5 #include<cmath>
     6 
     7 #define N 40007
     8 #define inf 1000000007
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 
    18 int n,k,ans,id,total;
    19 int cnt,hed[N],rea[N<<1],nxt[N<<1],val[N<<1];
    20 int tot,num[N],siz[N],f[N];
    21 bool vis[N];
    22 
    23 void add(int u,int v,int z)
    24 {
    25     nxt[++cnt]=hed[u];
    26     hed[u]=cnt;
    27     rea[cnt]=v;
    28     val[cnt]=z;
    29 }
    30 void get_heart(int u,int fa)
    31 {
    32     siz[u]=1,f[u]=0;
    33     for (int i=hed[u];i!=-1;i=nxt[i])
    34     {
    35         int v=rea[i];
    36         if (v==fa||vis[v]) continue;
    37         get_heart(v,u);
    38         siz[u]+=siz[v];
    39         f[u]=max(f[u],siz[v]);
    40     }
    41     f[u]=max(f[u],total-f[u]);
    42     if (f[u]<f[id]) id=u;
    43 }
    44 void dfs_dep(int u,int now,int fa)
    45 {
    46     num[++tot]=now;
    47     for (int i=hed[u];i!=-1;i=nxt[i])
    48     {
    49         int v=rea[i],fee=val[i];
    50         if (v==fa||vis[v]) continue;
    51         dfs_dep(v,now+fee,u);
    52     }
    53 }
    54 int calc(int u,int now)
    55 {
    56     tot=0;int res=0;
    57     dfs_dep(u,now,0);
    58     sort(num+1,num+tot+1);
    59     int l=1,r=tot;
    60     while(l<r)
    61     {
    62         if (num[l]+num[r]<=k) res+=r-l,l++;
    63         else r--;
    64     }
    65     return res;
    66 }
    67 void solve(int u)
    68 {
    69     ans+=calc(u,0);
    70     vis[u]=true;
    71     for (int i=hed[u];i!=-1;i=nxt[i])
    72     {
    73         int v=rea[i],fee=val[i];
    74         if (vis[v]) continue;
    75         ans-=calc(v,fee);
    76         total=siz[v],id=0;
    77         get_heart(v,u);
    78         solve(v);
    79     }
    80 }
    81 int main()
    82 {
    83     memset(hed,-1,sizeof(hed));
    84     n=read();
    85     for (int i=1;i<n;i++)
    86     {
    87         int x=read(),y=read(),z=read();
    88         add(x,y,z);
    89         add(y,x,z);
    90     }
    91     k=read();
    92     total=n,f[0]=inf;
    93     get_heart(1,-1);
    94     solve(id);
    95     printf("%d
    ",ans);
    96 }
     
  • 相关阅读:
    WannaCry蠕虫分析与预防
    对网络传输的理解
    RESTful API 设计最佳实践
    码农们的密码
    腾讯云公网负载均衡技术实现详解
    ELK统一日志系统的应用
    ElasticSearch + Canal 开发千万级的实时搜索系统
    聊架构:5分钟了解REST架构
    Netty5 HTTP协议栈浅析与实践
    这里,彻底了解HTTPS
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8835085.html
Copyright © 2020-2023  润新知