Tree Chain Partitioning

Tree Chain Partitioning

中国人戳这里

Background

Tree chain partitioning means that cut a tree into several edges

Some definitions

Heavy son: the son with the most Subnodes.

Light son: other sons except heavy son.

Heavy edge: the edge between root and heavy son

Light edge: the edge between root and light son.

Heavy chain: the chain that is only made of heavy edges.

Several theories

Noumenon

The most important theory: every node going to root will go through at most logN light edges.

And several easy theory:

1. Every node is at most in a heavy chain

2. There is no intersection between heavy chains.

Provement

I don't want to spend ink proving the second and third theory c because we can prove it just by the definition of heavy edges.

I will just prove the first theory.

If a node go through a light edge, we can know that there are at least one subtree is bigger than it.

So, the number of subnodes will increase at least one time. 

So, it is true that very node going to root will go through at most logN light sons or .heavy chains.

Algorithm core

 Appearently, we will cut the tree into different heavy edges.           

Pretreatment                                                                                                                                                                                                                                                                                                                        

Firsr, before we doing the main things, we should know the nodes belong to which heavy edges.

And to find each edge belongs to which edge, we should know the size of each subtree.

Of course, if we want to turn the tree to a line, you should find the dfs order.

It is true that you should dfs for two times.

And I think how to find them is easy.

So i just provide my code.

#include <bits/stdc++.h>
using namespace std;
struct Node
{
    int fa;// father
    int dep;// deep 
    int pos;// the heavy son 
    int heavy;// the orgin of heavy edge. 
    int size;// the size of subtree 
    int ds;//dfs order 
}tr[MAXN];
vector<int>vec[MAXN];
void dfs1(int now,int fa)// 我想知道我爹和我失散多年的重儿子 
{
    tr[now].size = 1;
    tr[now].dep = tr[fa].dep+1;
    int mx = 0 ;
    for(int i = 0;i < vec[now].size();i++)
    {
        if(vec[now][i] != fa)
        {
            dfs1(vec[now][i],now);    
            tr[now].size += tr[vec[now][i]].size;
            if(tr[vec[now][i]].size > mx)
            {
                mx = tr[vec[now][i]].size;
                tr[now].pos = vec[now][i];
            }
        }    
    } 
}
int tot = 0;
void dfs2(int now,int fa)
{
    tr[now].ds = ++ tot;
    if(tr[fa].pos == now) 
    {
        tr[now].heavy = tr[fa].heavy;
    }
    dfs2(tr[now].pos,now);
    for(int i = 0;i < vec[now].size();i++)
    { 
        if(vec[now][i] != fa && vec[now][i] != tr[now].pos)
        {
            dfs2(vec[now][i],now);
        }
    }
}

Linear Processing

Generally, the tree chain partitioning will use the segment tree.

And if it use the splay, it will be called Link Cut Tree.

And the operation of segment tree is that we will do a single point modification when we go through a light edge,

 and a Interval modification when we go through a heavy chain.

 

 About 

The tree chain partitioning is not a complete algorithm, it is just a way to spend logN time dealing with tree by the method of line.

 

转载于:https://www.cnblogs.com/mzyy1001/p/11205814.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值