删除最小数量的顶点以使所有顶点隔离

Posted

技术标签:

【中文标题】删除最小数量的顶点以使所有顶点隔离【英文标题】:Remove minimum number of vertices to make all the vertices isolated 【发布时间】:2015-09-06 01:31:00 【问题描述】:

我有一个无向连通图,我想通过删除不是边而是顶点来隔离它的所有顶点,我想将我删除的顶点数量保持在最低限度。我知道要实现这一点,我必须每次都删除度数最高的顶点,直到图形断开连接。但是我需要为它编写一个Java程序,我不知道如何跟踪最高度的顶点以及使用哪种数据结构。我得到以下输入。

V, E:分别为顶点和边的数量。A - B:指定边的顶点对

示例输入:

4 2
1-2
3-4

示例输出:2(即需要移除以使顶点隔离的最小顶点数)

约束:

1 <= V <= 10^5
1 <= E <= 3 * 10^5

【问题讨论】:

到目前为止你做了什么?您是否有需要使用的特定运行时间或空间? 【参考方案1】:

我赞同贪心算法在这里并不总是最优的想法,即使任务是隔离顶点,而不是断开图。

这里的问题是Vertex cover 问题,它是NP-hard。

举个简单的反例,看看这张取自here的图表:

贪心算法将从根开始,但这需要 4 个顶点而不是最优的 3 个。

【讨论】:

【参考方案2】:

我将从以下 DS 开始:

class Node

    int ID;
    int NumberOfNeighbors;
    List<int> NeighborIDs;

然后您继续将所有Nodes 保存在最大堆中(其中键为NumberOfNeighbors)。

你的算法应该是这样的:

int numberOfDeletedNodes = 0;

While (!heap.Empty)

    node = heap.PopTop();
    foreach (int ID in node.NeighborIDs)
    
        tempNode = heap.Extract(ID);
        tempNode.NumberOfNeighbors--;
        tempNode.NeighborIDs.Remove(node.ID);
        if (tempNode.NumberOfNeighbors != 0)
            heap.Insert(tempNode);
    

    numberOfDeletedNodes++;   

我可能错过了一些最终情况或其他东西,但总体思路是删除具有最多邻居的节点,照顾所有邻居*,然后继续直到堆为空。

* Important: if the neighbors has no more neighbors of its own, it doesn't go back in.

【讨论】:

如您所说,您错过了一些案例。我真的没有一个简单的小反例,但我偶然发现一个是[(21, 23), (19, 23), (19, 20), (17, 23), (17, 20), (17, 18), (11, 13), (11, 18), (11, 16), (13, 18), (13, 16), (4, 18), (4, 16), (3, 18), (3, 16), (2, 16)],其中一个数字表示许多(未连接)顶点的集合,而形式为(n, m) 的边表示每个n 顶点连接到所有m 顶点。在第一步中,您的算法将删除 17 个顶点组,尽管在最优解中并未删除。 对于图 0=[1, 2], 1=[0, 2, 3], 2=[0, 1, 3], 3=[1, 2, 4, 5 ], 4=[3, 5, 6], 5=[3, 4, 6], 6=[4, 5],该算法将给出 5 作为答案,但最小值为 4。请参阅@kitsune 的答案了解原因。

以上是关于删除最小数量的顶点以使所有顶点隔离的主要内容,如果未能解决你的问题,请参考以下文章

最小顶点覆盖

查找 MST 以使特定顶点具有最小度数

在有向图中找到可以到达其他顶点的最小顶点数[关闭]

断开图中的所有顶点 - 算法

hdu1054最小顶点覆盖

最小生成树