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

Posted

技术标签:

【中文标题】如何连接拓扑排序的 DAG 中的节点,以便每个上游节点最多可以到达任何下游节点 2 跳?【英文标题】:How to connect nodes in a topologically sorted DAG so that each upstream node can reach to any downstream node at most 2 hops? 【发布时间】:2021-01-16 05:22:48 【问题描述】:

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

n=3 的示例:

给定的线索是使用分而治之。如果有n个节点,如果我们假设前半部分的n/2已经有这个属性,最后n/2个也有这个属性,那么如何将这两部分结合起来,让n个节点有这个属性?该属性是如果我 和 j 都属于同一半,我们最多可以在 2 跳内从 i 到 j。显示如何 添加 theta(n) 附加边,这样如果 i 在前半部分,j 在后半部分,我们可以 仅使用两条边从 i 到 j。

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

【问题讨论】:

【参考方案1】:

一个简单的解决方案是从前半部分获取汇节点(一个具有 0 个出边的节点,如果使用这种方法构建 DAG 则应该只有一个),并从那里添加一条有向边到所有下半场的节点。这相当于添加 n/2 条边。然后,取出这个汇节点的所有祖先(前半部分的所有其他节点)并从它们添加一条边到汇节点。这将是另一个 (n/2)-1 条边,总计为线性数量的附加边。

根据归纳假设,后半部分以及前半部分已经具有 2 跳属性。前半部分的所有节点也将与后半部分的每个节点相距 2 跳。这条路径将从任何前半节点到原始汇节点,然后到后半节点的任何节点。我们现在有一个新的 DAG,它结合了 2 个 DAG,保留了 2 跳属性,并且有一个单一的 sink 节点。

该算法的分析类似于归并排序。我们将问题拆分为 2 个递归子问题,并有一个线性步骤组合结果。这形成了与合并排序相同的递归关系,并为我们提供了整体的 nlogn 复杂度。

【讨论】:

以上是关于如何连接拓扑排序的 DAG 中的节点,以便每个上游节点最多可以到达任何下游节点 2 跳?的主要内容,如果未能解决你的问题,请参考以下文章

拓扑排序(Topological Sorting)

[POJ3249]Test for Job [拓扑排序+DAG上的最长路径]

拓扑排序

CF-721C DAG图拓扑排序+费用DP

拓扑排序

拓扑排序+关键路径