• 树链剖分入门


    我学的学习资料:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html 和 ppt

    树链剖分可以解决很多问题,辅助一些线段树之类的数据结构可以解决一些树上修改的问题。还可以求LCA,不过复杂度比RMQ实现的LCA多一个log。

    下面是树链剖分实现的LCA:

     1 const int MAXN = 5e4 + 10;
     2 struct data {
     3     int to , next , cost;
     4 }edge[MAXN << 1];
     5 int head[MAXN] , cnt;
     6 int par[MAXN] , dep[MAXN] , top[MAXN] , id[MAXN] , dis[MAXN] , size[MAXN] , son[MAXN];
     7 
     8 void init() {
     9     memset(head , -1 , sizeof(head));
    10     cnt = 0;
    11 }
    12 
    13 inline void add(int u , int v , int cost) {
    14     edge[cnt].to = v;
    15     edge[cnt].next = head[u];
    16     edge[cnt].cost = cost;
    17     head[u] = cnt++;
    18 }
    19 //求size , par , son , dep
    20 void dfs_1(int u , int p , int d) {
    21     par[u] = p , size[u] = 1 , son[u] = u , dep[u] = d;
    22     for(int i = head[u] ; ~i ; i = edge[i].next) {
    23         int v = edge[i].to;
    24         if(v == p)
    25             continue;
    26         dis[v] = dis[u] + edge[i].cost; //离根的距离
    27         dfs_1(v , u , d + 1);
    28         if(size[v] > size[son[u]]) //取重儿子
    29             son[u] = v;
    30         size[u] += size[v];
    31     }
    32 }
    33 //求top , id
    34 void dfs_2(int u , int p , int t) { //p为父节点 t为链的祖先
    35     top[u] = t; //链的祖先
    36     id[u] = ++cnt; //点的顺序
    37     if(son[u] != u) //重儿子优先
    38         dfs_2(son[u] , u , t);
    39     for(int i = head[u] ; ~i ; i = edge[i].next) {
    40         int v = edge[i].to;
    41         if(v == p || v == son[u])
    42             continue;
    43         dfs_2(v , u , v); //树链重新开始
    44     }
    45 }
    46 //树链剖分求lca的复杂度是(nlognlogn),建议用RMQ求lca
    47 int lca(int u , int v) {
    48     int fu = top[u] , fv = top[v];
    49     while(top[u] != top[v]) { //链是否相同,不同就循环
    50         if(dep[fu] < dep[fv]) { //比较两个链的深度
    51             v = par[fv];
    52             fv = top[fv];
    53         }
    54         else {
    55             u = par[fu];
    56             fu = top[u];
    57         }
    58     }
    59     if(dep[u] >= dep[v]) //在相同的链上
    60         return v;
    61     return u;
    62 }
  • 相关阅读:
    笨办法学习python之hashmap
    python实现三级菜单源代码
    ql的python学习之路-day3
    ql的python学习之路-day2
    Spring的数据库开发
    Spring学习之Aspectj开发实现AOP
    spring学习之依赖注入DI与控制反转IOC
    spring学习之第一个spring程序
    spring学习之spring入门
    Java线程(一)——创建线程的两种方法
  • 原文地址:https://www.cnblogs.com/Recoder/p/5513387.html
Copyright © 2020-2023  润新知