ACM 算法集锦之图论专题

来源:互联网 发布:unity3d 5.0 教程 pdf 编辑:程序博客网 时间:2024/04/27 20:03

Floyd 算法

Floyd算法又称为弗洛伊德算法,插点法,是一种用于寻找给定的加权图中顶点间最短路径的算法。通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。

时间复杂度  O(n^3)

优缺点分析  Floyd算法适用于APSP(All Pairs Shortest Paths),是一种动态规划算法,稠密图效果最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高于执行|V|次Dijkstra算法

  优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单

  缺点:时间复杂度比较高,不适合计算大量数据。

代码:

void  floyd (Graph G,int n,Graph D,Graph P) 

{

     int i,j,k;

     for(i=0;i<n;i++)

          for(j=0;j<n;j++)

               {D[i][j] = G[i][j]; P[i][j] = i;}

     for(i = 0;i < n;i++) { D[i][i] = 0;P[i][i] = 0;}

     for(i=0;i<n;i++)

          for(j=0;j<n;j++)

               for(k=0;k<n;k++)

                    if(D[i][j]>D[i][k]+D[k][j])

                    {  D[i][j] = D[i][k]+D[k][j]; P[i][j] = P[k][j];}

}

 

 

求单源最短路径 Dijkstra算法

给定一个带权有向图G=(V,E),其中每天边的权是非负数。另外还给定一个V中一个顶点,称为源。计算从源到所有其他各个顶点的最短路长度。通常称为单源最短路径问题。

Dijkstra 算法是解决单源最短路径问题的一个贪心算法。该算法同时适用无向图和有向图。

伪代码如下:

清除所有点的标号

设d[0] = 0;其他d[i] = INF//为无穷大的整数d[i]表示distant(源到顶点i的最短路径长度)

循环n次

{在所有未标号的结点中,找出d值最小的结点x

   给结点x标记

   对于从x结点出发的所有边(x,y),更新d[y] = min{d[y],d[x]+w[x,y]}

  下面是对应的程序,假设起点是结点0,它到结点i的路径长度为d[i]。未标号结点v[i]=0,已标号结点v[i] = 1,为简单起见w[x][y]=INF表示边(x,y)不存在。

memset(v,0.sizeof(v));

for(int i=0;i<n;i++)  d[i] = (i==0 ? 0:INF);

for(int i=0;i<n;i++)

{

     int x,m = INF;

     for(int y = 0;y<n;y++)  if(!v[y] && d[y]< m) m =d[x=y];

    v[x] = 1;

   for(int y = 0;y<n;y++) d[y] =min(d[y],d[x]+w[x][y]);

}