我需要帮助来解决这个问题:
您有无向图G =(V,E),您想编写一种算法来调整所有 边之一,以便在获得的有向图中,进入节点的边的数量始终大于零。 对于所有边{u,v}∈E,您应该选择一个方向(u,v)或(v,u)。 如果答案是肯定的,则算法必须返回边缘的意图-满足要求
答案 0 :(得分:0)
正如所指出的,这个问题显然并不总能解决。由于每个顶点都必须至少有一个传入边,所以如果我们有E 因此,我们假设E> =V。这是一种算法的方法:首先,计算在O(E)时间内连接到每个顶点的边数。请注意,我的解决方案假定使用适当的存储,例如邻接表。您能看到邻接矩阵为何会具有更差的复杂性吗? 第二,我们将根据顶点的对应边数,以O(V)进行顶点的二进制最小堆运算。一些直觉:如果我们的顶点只有一条边,那么我们必须将其转换为输入边!当我们指定该边的方向时,我们需要更新另一侧顶点的边数。如果该另一个顶点从2个边变为1,则现在我们不得不指定其左一个边的方向。视觉上: 1-2-1 任意选择1个边缘计数以进行定向 1-2-> 0 2刚刚失去优势,所以请更新为1! 1-1-> 0 由于现在只有1条边线,因此将其边线转换为传入边! 0-> 0-> 0 显然,从V> E开始,该图不起作用,但是您明白了。 因此,V次,我们从堆中提取最小值并固定为O(logV)。每次减少邻居的边缘计数。假设邻接表,我们可以找到一个邻居(第一个元素)并在O(1)中更新计数,然后可以在O(logV)中再次修复堆。总体而言,此步骤需要O(V logV)。 请注意,如果我们所有剩余的顶点都具有多个可能的边,则此方法将任意选择边数最少的一个顶点,并任意选择其边之一。我将让您考虑一下为什么这样做(如果您认为不行,请尝试提供一个反例!)最后,如果E> V,那么当我们完成操作时,可能会留下多余的多余边缘。在O(E)时间里,我们可以为这些边缘任意分配方向。 总体而言,我们正在查看V + V * logV + E aka O(E + VlogV)。希望这会有所帮助!