zoukankan      html  css  js  c++  java
  • CodeForces 161D Distance in Tree 树上点分治

    题目传送门

    题意:给你一颗树,问你有多少个点对满足他们的距离恰好为k。

    题解:

    很裸的一个点分治。

    1.找到重心。

    2.对每一棵子树中的每一个点,都直接询问k-deep的个数,加到答案里,每次处理对一棵子树询问完之后,把这个树的每个节点的深度加到deep的个数里。

    3.对个数清0,然后处理每一棵子树的信息。

    4.重复1-4的处理,直到没有树了。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
     4 #define LL long long
     5 #define ULL unsigned LL
     6 #define fi first
     7 #define se second
     8 #define pb push_back
     9 #define lson l,m,rt<<1
    10 #define rson m+1,r,rt<<1|1
    11 #define lch(x) tr[x].son[0]
    12 #define rch(x) tr[x].son[1]
    13 #define max3(a,b,c) max(a,max(b,c))
    14 #define min3(a,b,c) min(a,min(b,c))
    15 typedef pair<int,int> pll;
    16 const int inf = 0x3f3f3f3f;
    17 const LL INF = 0x3f3f3f3f3f3f3f3f;
    18 const LL mod =  (int)1e9+7;
    19 const int N = 1e5 + 100;
    20 vector<int> vc[N];
    21 int n, k, u, v;
    22 int sz[N], vis[N];
    23 int mxr, rt;
    24 void Getw(int o, int u, int num){
    25     sz[u] = 1;
    26     int mx = 0;
    27     for(int i = 0; i < vc[u].size(); ++i){
    28         int v = vc[u][i];
    29         if(o == v || vis[v]) continue;
    30         Getw(u, v, num);
    31         sz[u] += sz[v];
    32         mx = max(sz[v], mx);
    33     }
    34     if(o) mx = max(mx, num - sz[u]);
    35     if(mx < mxr) mxr = mx, rt = u;
    36 }
    37 int cnt[N];
    38 LL ans = 0;
    39 void DFS(int o, int u, int deep){
    40     cnt[deep] += 1;
    41     sz[u] = 1;
    42     for(int i = 0; i < vc[u].size(); ++i){
    43         int v = vc[u][i];
    44         if(vis[v] || v == o) continue;
    45         DFS(u, v, deep+1);
    46         sz[u] += sz[v];
    47     }
    48 }
    49 void cal(int o, int u, int deep){
    50     int m = k - deep;
    51     if(m < 0) return ;
    52     ans += cnt[m];
    53     for(int i = 0; i < vc[u].size(); ++i){
    54         int v = vc[u][i];
    55         if(vis[v] || v == o) continue;
    56         cal(u, v, deep+1);
    57     }
    58 }
    59 void GG(int u, int num){
    60     if(num == 1) return ;
    61     mxr = inf;
    62     Getw(0, u, num);
    63     vis[rt] = 1;
    64     for(int i = 0; i < vc[rt].size(); ++i){
    65         int v = vc[rt][i];
    66         if(vis[v]) continue;
    67         cal(0, v, 1);
    68         DFS(0, v, 1);
    69     }
    70     int nrt = rt;
    71     for(int i = 1; i <= mxr; i++) cnt[i] = 0;
    72     for(int i = 0; i < vc[nrt].size(); ++i){
    73         int v = vc[nrt][i];
    74         if(vis[v]) continue;
    75         GG(v, sz[v]);
    76     }
    77 }
    78 int main(){
    79     scanf("%d%d", &n, &k);
    80     for(int i = 1; i < n; ++i){
    81         scanf("%d%d", &u, &v);
    82         vc[v].pb(u);
    83         vc[u].pb(v);
    84     }
    85     cnt[0] = 1;
    86     GG(1, n);
    87     printf("%I64d
    ", ans);
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    Android开发 使用 adb logcat 显示 Android 日志
    【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410
    C语言 结构体相关 函数 指针 数组
    C语言 命令行参数 函数指针 gdb调试
    C语言 指针数组 多维数组
    Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
    C语言 内存分配 地址 指针 数组 参数 实例解析
    CRT 环境变量注意事项
    hadoop 输出文件 key val 分隔符
    com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Too many connections
  • 原文地址:https://www.cnblogs.com/MingSD/p/9761920.html
Copyright © 2011-2022 走看看