我很感激以下问题的建议/算法:
考虑具有由E边连接的V顶点的图(V,E <= 10 ^ 5)。删除顶点后,将删除连接到该顶点的所有边。顶点标记为1,2,...,V。
在E行上给出输入,并且在每一行上有两个以空格分隔的顶点数,表示这两个顶点之间的边。接下来的V行是1,2,...,V的置换,表示顶点被移除的顺序。输出V行表示每个步骤是否连接了图形(即每对顶点之间有一系列路径)。 V和E是已知的,在输入的第一行上以空格分隔的整数给出。
例如,请考虑以下示例输入(边缘是无向的):
5 5
1 2
3 1
2 3
2 4
5 4
3
4
1
2
5
第一行表示有5个顶点和5个边。接下来的5行描述了边缘(它们是无向的,即从1到2的边缘也可以从2到1)。之后的5行给出了顶点被移除的顺序。
对于此示例,我们将获得如下输出:
当顶点3被移除时,图形被连接,因为我们可以从1,2,4,5中的任何一个到1,2,4,5中的任何一个。当移除顶点4时,图形被断开因为顶点5没有连接。当顶点1被移除时,存在同样的问题。当顶点2被移除时,只剩下5个,因此图形被连接。删除所有顶点后,图表就会连接起来。
我尝试了一种天真的递归方法,检查是否可以从起始顶点到终点:
void dfs(int start, int curr, int end):
if (curr == 0): // start condition, i.e. curr not yet initialized
curr = start
if (curr == end):
return true
else:
for (int v : edges[curr]):
dfs(start, v, end)
return false
检查每一步是否可以使用上述算法从所有顶点A行进到所有其他顶点B太慢(O(V ^ 2 * E ^ V),算法理想情况下应为O(V log) V),或者可能在大约一秒钟内运行O(V ^ 2)。
答案 0 :(得分:0)
对于分区图的每个步骤存储数量。对于初始图形,它是通过从初始顶点执行完全遍历(DFS或BFS)来完成的,而不是从尚未覆盖的顶点重复遍历。如果分区数<= 1,则连接图形。
如果删除的顶点的度数为0,则分区数减少一个。
如果删除的顶点的度数为1,则分区数保持不变。
如果删除的顶点的度数大于1,则可以将分区数增加max degree-1。通过从移除顶点的邻居的类似遍历来检查。从最初的邻居开始,找到与之相连的所有邻居。重复从未访问的neigbour遍历。