Algorithm 如何证明一个线性算法,该算法可以识别图中的所有圈和长度,其中每个顶点正好有一条输出边

Algorithm 如何证明一个线性算法,该算法可以识别图中的所有圈和长度,其中每个顶点正好有一条输出边,algorithm,graph-theory,graph-algorithm,Algorithm,Graph Theory,Graph Algorithm,考虑n个顶点上的一个有向图,其中每个顶点都有 一个向外的边缘。此图由以下循环集合组成: 以及其他具有循环路径的顶点,我们 呼叫分支机构。描述一个线性时间算法,用于识别 所有循环,并计算每个循环的长度。你可以 假设输入作为数组A给出,其中A[i]是 i的邻居,因此图有边(i,A[i]) 到目前为止,我的算法基本上是标记我穿过的顶点,每次一个顶点指向我穿过的顶点时,我计算一个周期,然后移动到下一个未访问的顶点。在这个过程中,我还有一个hashmap或其他东西来记录每个节点的遍历顺序,这样我就可以在识

考虑n个顶点上的一个有向图,其中每个顶点都有 一个向外的边缘。此图由以下循环集合组成: 以及其他具有循环路径的顶点,我们 呼叫分支机构。描述一个线性时间算法,用于识别 所有循环,并计算每个循环的长度。你可以 假设输入作为数组A给出,其中A[i]是 i的邻居,因此图有边(i,A[i])


到目前为止,我的算法基本上是标记我穿过的顶点,每次一个顶点指向我穿过的顶点时,我计算一个周期,然后移动到下一个未访问的顶点。在这个过程中,我还有一个hashmap或其他东西来记录每个节点的遍历顺序,这样我就可以在识别循环时计算长度。(这是线性的吗?)

colors = [0] ** N; # initialize N element array withe values of zero (not seen)
for i in range(N):
    v = i # current vertex
    if colors[v] != 0: continue # already seen
    colors[v] = 1 # seen
    v = A[v] # move to neighbor
    while colors[v] == 0:
       colors[v] = 1
       v = A[v] # move to neighbor
    # we have reached previously seen node; this is the start node of a cycle
    colors[v] = 2 # mark the start of a cycle
    cycle_len = 1
    v = A[v] # move to neighbor
    while colors[v] == 1:
       cycle_len += 1
       v = A[v] # move to neighbor
   print("got a cycle with length =", cycle_len)
其基本思想是使用三种颜色分别标记已访问的节点和作为循环起点的节点;显然,单个节点只能属于单个循环

该算法是线性的,因为内部
,而
循环只对以前未见过的节点执行。跳过已看到的节点。在最坏的情况下,两个内部while循环都被完全执行,但2*N仍然是O(N)


使用hashmap不符合要求,因为hashmaps最坏情况下的时间复杂度不是线性的。

也许这个问题更适合于或?算法是否允许使用额外的O(n)内存(例如,如果顶点已经访问过,则标记?)问题是算法的描述不明确,因此,无法判断您要实现的算法是否正确。首先,要具体。并使用数组而不是哈希映射,这样您就可以使用实时线性时间而不是预期的线性时间。@kfx内存似乎不是问题请注意,引用的问题不需要正式证明。如果你知道你的算法是有效的,你只需要解释你是如何知道的。实现和证明是两件完全不同的事情。算法的形式证明是非常形式化的。@LasseV.Karlsen抱歉,我说它听起来需要一个形式证明,但它只需要证明算法是正确的