代码改变世界

算法导论-每对顶点间的最短路径习题解

2012-04-13 12:02  meteorgan  阅读(1034)  评论(0编辑  收藏  举报

25.1-10 写出一个有效的算法来计算图中最短路径的负权回路的长度(即所包含的边数)。

  解:在SLOW-ALL-PAIR-SHORTEST-PATHS()计算L(m)的过程中,第一次发现有对角元素小于0,则该m为所求的长度。如果m=n+1是仍未有主元元素的值小于0,则图中没有负权回路。时间复杂度为O(n4)。

 

25.2-9 假定一个有向无环图的传递闭包可以在f(|V|,|E|)时间内计算,其中f是|V|和|E|的单调递增函数。证明:计算一般有向图G=(V,E)的传递闭包G*=(V,E)的时间为f=(|V|,|E|)+O(V+E*)。

  解:1. 计算图G的强连通分支。时间O(V+E)。

    2. 计算分支图GSCC 的传递闭包,由于分支图是有向无环图,且边数不多于|V|,顶点数不多于|G|,f是|V|,|G|的单调递增函数,所以此过程可以在f(|V|+|E|)内完成。

         3. 每个连通分支内部所有顶点是相互可达的,对于可通过分支图的传递闭包计算某个分支内的顶点是否对其他分支内的顶点可达。总时间为O(V+E*)。

 

25-1 动态图的传递闭包

  解:a) 还是代码比较直观:

1 insert_edge(u, v, G)
2      for i in |V|
3          for j in |V|
4              if T[i, u] ==1 and T[v, j] == 1
5                  T[i,j] = 1

     b) 对于一条链的情况: v1->v2->v3 .... ->vn,如果添加边vn->v1,则原来布尔矩阵中有n(n+1)/2个元素,加入边vn->v1后,矩阵中有n2个元素,因此时间复杂度为O(n2).

          c)有向图中至多有V2条边, 因此若直接采用a)中方法,时间复杂度为O(V4)。另外,a)中第5行存在冗余情况,如果T[v,j] = 1成立,则无须进行这一步。代码可以做如下改进:

1 insert_edge(u, v, G)
2       for i in |V|
3             if T[i,u] == 1 and T[v,j] ==0
4                 for j in |V|
5                     T[i,j] = 1

 

           这种改进没有改变插入单条边的时间复杂度。但改变了第4行的执行次数,当连续插入n次时, 第4行至多执行V2次,每次需要|V|步,所以总的时间复杂度为O(V3)。