如何在拓扑排序的DAG中连接节点,以便每个上游节点最多可以到达2个跃点到达任何下游节点?

问题描述

我正在尝试解决此问题:给定n个节点,我需要插入边以形成拓扑排序的DAG类型的情况。每个节点都应该能够通过1跳或2跳路径(不更长)到达任何下游节点。我最多使用theta(nlogn)边缘来执行此操作。我该怎么办?

n = 3的示例:

enter image description here

给出的线索是使用分而治之。如果存在n个节点,并且假设上半部分的n / 2已经具有此属性,而最后n / 2也具有此属性,那么如何将这两个半部分组合在一起,以便n个节点具有此属性?财产是如果我 和j都属于同一个一半,我们最多可以从i到j跳两跳。 添加theta(n)附加边,以便如果i在上半部而j在下半部中,我们可以 从i到j仅使用两条边。

我该怎么做?我尝试将上半部分的叶子连接到下半部分的每个节点,然后对叶子的祖父母进行相同操作,依此类推。但这使用(n / 4)* n,它是二次方。

解决方法

一个简单的解决方案是从上半部分开始接收节点(一个具有0个向外边缘的节点,如果使用这种方法构建DAG,则应该只有一个),然后从那里添加一个有向边缘。下半年的节点。这等于增加n / 2条边。然后,获取此接收器节点的所有祖先(上半部分中的所有其他节点),并将其边缘添加到接收器节点。这将是另外(n / 2)-1个边缘,总共是线性数量的附加边缘。

根据归纳假设,后半部分和前半部分将已经具有2跳属性。上半部分的所有节点到下半部分的每个节点也将相距2跳。该路径将是从任何前一半节点到原始接收器节点,然后再到后一半中的任何节点。现在,我们有了一个新的DAG,它结合了2个DAG,保留了2跳属性,并具有单个接收器节点。

此算法的分析类似于合并排序。我们将问题分为2个递归子问题,并通过线性步骤组合了结果。这形成了与归并排序相同的递归关系,并为我们提供了总体的登录复杂度。