• POJ 1741 树上点分治


    题意:

    求树上的距离小于等于K的点对个数

    题解:

    树分治论文题。

    需要者请移步qzc论文~

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cstdio>
      5 #include <cstdlib>
      6 
      7 #define N 200000
      8 #define M 400000
      9 #define INF 0x3f3f3f3f
     10 
     11 using namespace std;
     12 
     13 int head[N],next[M],to[M],len[M];
     14 int sz[N],lim[N],dis[N];
     15 bool vis[N];
     16 int n,cnt,root,tot,mn,md;
     17 
     18 inline void add(int u,int v,int w)
     19 {
     20     to[cnt]=v; len[cnt]=w; next[cnt]=head[u]; head[u]=cnt++;
     21 }
     22 
     23 inline void read()
     24 {
     25     memset(head,-1,sizeof head); cnt=0;
     26     for(int i=1,a,b,c;i<n;i++)
     27     {
     28         scanf("%d%d%d",&a,&b,&c);
     29         add(a,b,c); add(b,a,c);
     30     }
     31 }
     32 
     33 inline void getsize(int u,int fa)
     34 {
     35     sz[u]=1; lim[u]=0;
     36     for(int i=head[u];~i;i=next[i])
     37         if(to[i]!=fa&&!vis[to[i]])
     38         {
     39             getsize(to[i],u);
     40             sz[u]+=sz[to[i]];
     41             lim[u]=max(lim[u],sz[to[i]]);
     42         }
     43 }
     44 
     45 inline void getroot(int p,int u,int fa)
     46 {
     47     lim[u]=max(lim[u],sz[p]-sz[u]);
     48     if(lim[u]<mn) mn=lim[u],root=u;
     49     for(int i=head[u];~i;i=next[i])
     50         if(to[i]!=fa&&!vis[to[i]]) getroot(p,to[i],u);
     51 }
     52 
     53 inline void getdis(int u,int fa,int d)
     54 {
     55     for(int i=head[u];~i;i=next[i])
     56         if(to[i]!=fa&&!vis[to[i]]) getdis(to[i],u,d+len[i]);
     57     dis[++tot]=d;
     58 }
     59 
     60 inline int calc(int u,int fa,int d)
     61 {
     62     tot=0;
     63     getdis(u,fa,d);
     64     sort(dis+1,dis+1+tot);
     65     int res=0;
     66     for(int i=1,j=tot;i<j;i++)
     67     {
     68         while(i<j&&dis[i]+dis[j]>md) j--;
     69         if(i>=j) break;
     70         res+=j-i;
     71     }
     72     return res;
     73 }
     74 
     75 inline int getans(int u,int fa)
     76 {
     77     getsize(u,fa);
     78     mn=INF;
     79     getroot(fa,u,fa);
     80     int rt=root;
     81     int res=calc(rt,rt,0);
     82     vis[root]=true;
     83     for(int i=head[rt];~i;i=next[i])
     84         if(to[i]!=fa&&!vis[to[i]])
     85         {
     86             res-=calc(to[i],rt,len[i]);
     87             res+=getans(to[i],rt);
     88         }
     89     return res;
     90 }
     91 
     92 inline void go()
     93 {
     94     memset(vis,0,sizeof vis);
     95     printf("%d\n",getans(1,1));
     96 }
     97 
     98 int main()
     99 {
    100     while(scanf("%d%d",&n,&md),n||md) read(),go();
    101     return 0;
    102 }
  • 相关阅读:
    MyBatis3系列__01HelloWorld
    localStorage、sessionStorage、Cookie的区别及用法
    Javascript数组原型方法大全以及实例!!
    如何使用正则表达式以及封装函数?
    收藏多年的正则表达式笔记大全,绝对是干货!
    手写Ajax的意义所在,从青铜到钻石!
    Git的常用命令
    阿里云部署服务器流程
    MongoDB常用数据库命令第二集
    vuex简单化理解和安装使用
  • 原文地址:https://www.cnblogs.com/proverbs/p/2868721.html
Copyright © 2020-2023  润新知