有序图中最长的路径

时间:2014-11-06 23:36:47

标签: algorithm

设G =(V,E)是具有节点v_1,v_2,...,v_n的有向图。如果G具有以下属性,我们说G是有序图。

  • 每个边缘从索引较低的节点到具有较高索引的节点。也就是说,每个有向边具有形式(v_i,v_j),其中i <1。学家
  • 除v_n之外的每个节点至少有一个边缘离开它。也就是说,对于每个节点v_i,存在形式的至少一个边缘(v_i,v_j)。

给出一个有效的算法,该算法采用有序图G并返回从v_1开始并以v_n结束的最长路径的长度。

如果你想看到漂亮的乳胶版本:here

我的尝试:

动态编程。 Opt(i)= max {Opt(j)} + 1.对于所有j,这样的j可以从i到达。

是否有更好的方法可以做到这一点?我认为即使有记忆,我的算法仍然是指数级的。 (这只是我在网上找到的旧期中期评论)

2 个答案:

答案 0 :(得分:2)

你的方法是对的,你必须做

Opt(i) = max {Opt(j)} + 1} for all j such that j is reachable from i

但是,只有在没有记忆的情况下运行它才会呈现指数。通过memoization,您将获得每个节点j,j&gt;的memoized最佳值。我,当你在节点i。

对于最坏情况的复杂性,让我们假设每两个可以连接的节点都是连接的。这意味着,v_1(v_2, v_3, ... v_n)相关联; v_i(v_(i+1), v_(i+2), ... v_n)相关联。

顶点数(V)= n

因此,边数(E)= n*(n+1)/2 = O(V^2)

让我们将注意力集中在顶点v_k上。对于这个顶点,我们必须经历已经导出的(n-k)节点的最佳值。

直接到达v_k的方式数量=(k-1)

因此最坏情况时间复杂度=&gt; sigma((k-1)*(n-k)) from k=1 to k=n,这是幂2的多项式的sigma,因此会导致O(n^3)时间复杂度。

简单地说,最坏的情况时间复杂度是O(n^3) == O(V^3) == O(E) * O(V) == O(EV)

答案 1 :(得分:1)

由于第一个属性,这个问题可以解决O(V ^ 2)甚至更好的O(E),其中V是顶点数,E是边数。实际上,它使用的动态编程方法与您提供的方法非常相似。设opt [i]是v_1到v_i的最长路径的长度。然后

opt[i] = max(opt[j]) + 1 where j < i and we v_i and v_j is connected, 
                         using this equation, it can be solved in O(V^2). 

更好的是,我们可以用另一种顺序解决这个问题。

int LongestPath() {
   for (int v = 1; v <= V; ++v) opt[v] = -1;
   opt[1] = 0;
   for (int v = 1; v <= V; ++v) {
     if (opt[v] >= 0) {
     /* Each edge can be visited at most once,
        thus the runtime time is bounded by |E|.
      */ 
      for_each( v' can be reached from v) 
         opt[v'] = max(opt[v]+1, opt[v']);
    }
  }
 return opt[V];

}