我有一个图表和一个起始节点。我想找到当我使用DFS删除图中所有节点中的每个节点时有多少节点被隔离。
例如,如果我从固定节点1开始,并删除节点2,我将拥有多少个孤立节点?如果我删除节点3?
我知道我可以为所有节点做DFS(每次删除一个不同的节点),但是这样做我将不得不为每个节点导航一次图形,我想用一次运行来解决它。
我被告知它有O(| V | * || A |),是| V | =边数,| A | =节点数。
我一直在玩prenum和postnums,但没有成功。
答案 0 :(得分:1)
令N为顶点数,M为边数。如果您只是想要一个O(NM)解决方案,那么除了为每个顶点运行DFS之外,您不需要做任何其他事情。
每个DFS的复杂度为O(N + M),因此总复杂度为O(N(N + M))= O(N 2 + NM)。通常我们有比顶点更多的边缘,因此NM的增长速度比N²快得多,我们可以说复杂度是O(NM)。但请记住,如果你在每个步骤中物理删除当前顶点,你的实现将会有更复杂的复杂性,因为物理删除顶点意味着从许多邻接列表中删除条目,无论你如何代表图形。有一个实现技巧可以加快进程:不是在每个DFS之前物理删除当前顶点,只需将顶点标记为已删除,当您在DFS期间浏览邻接列表时,只需忽略标记的顶点。
但是,我觉得你可以使用Tarjan算法找到关节点,在O(N + M)中解决这个问题。该算法将找到每个顶点,当从图中移除时,将图形拆分为多个连接的组件(这些顶点称为清晰点)。如果删除不是关节点的顶点,很容易看出不会有孤立的顶点。但是,如果删除关节点,则将图形分为G和G'两部分,其中G是起始顶点的连通分量,G'是图形的其余部分。来自G'的所有顶点都是孤立的,因为如果从起始顶点运行DFS,则无法到达它们。我认为您可以有效地找到每个顶点删除的G'大小,也许您甚至可以在运行Tarjan时执行此操作。如果我找到了解决方案,我可以稍后编辑这个答案。
编辑:我设法解决了O(N + M)中的问题。我会给你一些提示,以便你自己找到答案:每个无向图可以在(不是不相交的)双连通分量集中分解:每个双连通分量是图的顶点的子集,即使你删除任何顶点,该子集中的每个顶点都将保持连接状态。图表
可以改变找到桥梁和关节点的Tarjan O(N + M)算法,以便找到双连通分量,找出哪些顶点属于每个双连通分量,或哪些双连通分量包含每个顶点
如果删除任何不是关节点的顶点,那么这个顶点的答案显然是N-1
如果删除关节点,则起始顶点的同一双连通分量中的每个顶点仍然是可访问的,但您不知道其他双连通分量。别担心,有一种方法可以有效地找到它
您可以压缩其双连通组件的图B中的每个图G.压缩算法很简单:每个双连通组件都成为B中的顶点,并链接共享某些关节点的双连通组件。我们可以证明结果图B是树。您必须以某种方式使用此树以解决步骤4中提出的问题