【问题标题】:Given a directed weighted graph with self loops ,find the list of nodes that are exactly k dist from a given node x?给定一个带有自环的有向加权图,找到与给定节点 x 正好是 k 距离的节点列表?
【发布时间】:2016-12-13 13:46:45
【问题描述】:

图中每条边的权重为1,图可能有环,如果一个节点有自环,它可以是从0到无穷大的任意距离,具体取决于编号。我们采取自我循环的时间。

我已经使用 bfs 解决了这个问题,但是距离的限制是 10^9 的顺序,因此 bfs 很慢。

我们将被要求对表单的给定图表进行多个查询 (距离,来源) o/p 是从源顶点开始的给定距离的节点列表。

约束

1<=Nodes<=500
1<queries<=500
1<=distance<=10^9

我有一种感觉,会有很多重复的计算。节点很小,但我无法弄清楚如何在较小的问题中减少问题。

这样做的有效方法是什么?

编辑:我尝试过使用矩阵求幂,但对于给定的约束,它太慢了。该问题的时间限制为 1 秒。

【问题讨论】:

    标签: algorithm graph dynamic-programming cycle


    【解决方案1】:

    G = (V,E)成为你的图,并定义邻接矩阵A如下:

    A[i][j] = 1       (V[i],V[j]) is in E
              0       otherwise
    

    在这个矩阵中,对于每个k

    (A^k)[i][j] > 0 if and only if there is a path from v[i] to v[j] of length exactly k.
    

    这意味着通过创建此矩阵然后计算指数,您可以轻松得到答案。

    对于快速指数计算,您可以使用exponent by squaring,这将产生O(M(n)^log(k)),其中M(n) 是nXn 矩阵的cost for matrix multiplication

    当您在同一张图上查找不同的查询时,这也将节省一些计算。

    附录 - 索赔证明:

    基础:A^1 = A,实际上在A 中定义,A[i][j]=1 当且仅当(V[i],V[j])E

    假设:假设所有l&lt;k 的声明都是正确的

    A^k = A^(k-1)*A。根据归纳假设,A^(k-1)[i][j] &gt; 0 当且仅当存在从V[i]V[j] 的长度为k-1 的路径。

    让我们检查两个顶点v1,v2,索引为ij
    如果它们之间存在长度为k 的路径,则设为v1-&gt;...-&gt;u-&gt;v2。设u 的索引为m
    来自 i.h. A^(k-1)[i][m] &gt; 0 因为有路径。另外A[m][j] = 1,因为(u,v2) = (V[m],V[j])是一条边。

    A^k[i][j] = A^(k-1)*A[i][j] = A^(k-1)[i][1]A[1][j] + ... + A^(k-1)[i][m]A[m][j] + ... + A^(k-1)[i][n]A[n][j] 
    

    既然A[m][j] &gt; 0A^(k-1)[i][m] &gt; 0,那么A^(k-1)*A[i][j] &gt; 0

    如果没有这样的路径,那么对于每个顶点 u 使得 (u,v2) 是一条边,从 vu 没有长度为 k-1 的路径(否则 v1-&gt;..-&gt;u-&gt;v2是一条长度为 k) 的路径。

    然后,使用归纳假设我们知道如果A^(k-1)[i][m] &gt; 0 那么A[m][j] = 0,对于所有m
    如果我们在定义 A^k[i][j] 的总和中分配它,我们会得到 A^k[i][j] = 0

    QED

    小提示:从技术上讲,A^k[i][j]ij 之间的路径数,长度正好为k。这可以证明与上面类似,但更多地关注细节。
    为了避免数字增长过快(这将增加M(n),因为您可能需要大整数来存储该值),并且由于您不关心 0/1 以外的值 - 您可以处理矩阵作为布尔值 - 仅使用 0/1 值并修剪其他任何值。

    【讨论】:

    • 对于小 k 和大 n,朴素的 BFS 方法会更便宜。否则,这就是要走的路。
    • 虽然您的方法是正确的,但对于 500x500 到 10^9 的矩阵的 500 次查询来说太慢了。原题的时间限制为 1 秒。
    • 我用你的方法解决了 + faster multiplication for boolean matrix
    【解决方案2】:

    如果你的图中有循环,那么你可以推断cycle * N + 1中的每个相邻节点之间都有一个链接,因为你可以随意迭代。

    这让我想到了这个主意,我们可以利用循环来发挥我们的优势!
    在检测循环时使用 BFS,我们计算offset + cycle*N,然后我们尽可能接近我们的目标(K)

    然后很容易地搜索 K。

    例如

    A -> B -> C -> D -> B K = 1000; S = A;

    A - 0
    B - 1
    C - 2
    D - 3
    B - 1 (+ 4N)
    在这里你可以查看k - (1+4N) = 0的floor() > 1000 - 1 - 4N = 0 > 999 = 4N > N=249 => 最好的B是249*4 + 1 = 997
    更简单的方法是计算:round(k - offset, cycle)

    从这里您只能再数几步。
    在这个例子中(作为一个正则表达式):A(BCD){249}BCD

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      相关资源
      最近更新 更多