我有一个无向连通图,我想通过删除边而不是顶点来隔离它的所有顶点,我想保持我删除的顶点数量最少。我知道要实现这一点,我必须每次都移除具有最高度数的顶点,直到图形断开连接。但我需要为它编写一个Java程序,我不知道如何跟踪具有最高程度的顶点以及要使用的数据结构。我得到以下输入。
{V, E}
:顶点数和边数。
{A - B}
:指定边
示例输入:
4 2
1-2
3-4
示例输出:2
(这是为了使顶点隔离而需要移除的最小顶点数)
约束:
1 <= V <= 10^5
1 <= E <= 3 * 10^5
答案 0 :(得分:1)
我认为贪婪算法在这里并不总是最优,即使任务是隔离顶点,而不是断开图形。
这里的问题是Vertex cover问题,它是NP难的。
对于快速反例,请考虑此图表取自here:
贪婪算法将从根开始,但这需要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。