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

时间:2015-09-06 01:31:00

标签: graph

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

{V, E}:顶点数和边数。
{A - B}:指定边

的顶点对

示例输入:

4 2
1-2
3-4

示例输出:2(这是为了使顶点隔离而需要移除的最小顶点数)

约束:

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

3 个答案:

答案 0 :(得分:1)

我认为贪婪算法在这里并不总是最优,即使任务是隔离顶点,而不是断开图形。

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

对于快速反例,请考虑此图表取自here

Greedy algorithm does not work

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

答案 1 :(得分:0)

我将从以下DS开始:

class Node
{
    int ID;
    int NumberOfNeighbors;
    List<int> NeighborIDs;
}

然后继续将所有Node保留在最大堆中(密钥为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.

答案 2 :(得分:0)

继续移除具有最高度数的顶点并不总是导致移除最少数量的顶点。 考虑具有4个顶点v1到v4的完全连通图(因此每个具有度数3)。现在添加两个顶点v5和v6以及三个边(v3,v5),(v4,v5),(v5,v6)。然后删除v5会断开图形,因为v6不再连接到v1到v4,但v5的程度为3,而v4和v3的程度为4。