重光分解问题

时间:2016-07-28 18:19:58

标签: algorithm tree depth-first-search

我正在研究HLD,我发现我需要4件事:

  • 给定一个节点,知道它的链条;
  • 给定一个节点,知道它在链中的位置;
  • 鉴于链条,知道它的头;
  • 给定链条,知道它的长度。

我能够做到这四件事中的3件,但我不能做第二件事。

我是在树上使用单个dfs做的,而我想知道是否可以(以及如何)在我的代码中添加一些东西来解决第二个问题

以下是代码:

#define maxn 1010

int SizeOf[maxn], SpecialChildOf[maxn],
    ChainOf[maxn], SizeOfChain[maxn], HeadOfChain[maxn];
int chain = 0;
vector<int> T[maxn];

void dfs(int u){
    SizeOf[u] = 1;
    int adj = T[u].size();
    if(!adj){
        ChainOf[u] = chain;
        SpecialChildOf[u] = -1;
        HeadOfChain[chain] = u;
        SizeOfChain[chain]++;
        return;
    }
    dfs(T[u][0]);
    int specialChild = T[u][0];
    SizeOf[u] += SizeOf[specialChild];

    for(int i = 1; i < adj; i++){
        int v = T[u][i];
        chain++;
        dfs(v);
        if(SizeOf[v] > SizeOf[specialChild]) specialChild = v;
        SizeOf[u] += SizeOf[v];
    }

    SpecialChildOf[u] = specialChild;
    ChainOf[u] = ChainOf[specialChild];
    SizeOfChain[ChainOf[u]]++;
    HeadOfChain[ChainOf[u]] = u;
}

它做什么?它是一个简单的dfs,你从链0开始,沿着树一直向下,而不改变当前的链。当您到达叶节点时,您指定此节点是当前链的最后一个元素(并将当前链的大小增加1)并返回上一个节点。当你回来时,你会看到节点的其他子节点,向每个子节点传递一个不同的链,并且在从所有节点返回之后,所有节点之间最大的子节点链成为当前节点的链,然后它会回来。

1 个答案:

答案 0 :(得分:0)

一种方法是通过在返回语句之前添加代码来将距离存储到链的末尾:

DistanceToEnd[u] = SizeOfChain[ChainOf[u]];

在深度优先搜索完成后,您可以通过以下方式计算链中的位置:

distanceToStart = SizeOfChain[ChainOf[u]] - DistanceToEnd[u];