版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pt_raspi_fresher/article/details/87733101
-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删.
第一:
最短路径 (Shortest Path)
? 最短路径问题 : 如果从有向图中某一顶点( 称为源点) 到达另一顶点( 称为终点 ) , 如 的路径可能不止一条 , 如何找到一条 路径使得沿此路径上各边上的权值总和达到最小 。
? 问题解法
? 单源最短路径问题
•Dijkstra 算法
? 所有顶点之间的最短路径
•Floyd 算法
问题分析
解决步骤描述
算法精髓
举例 :源点为0
第二:
最短路径算法的实现
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define VNUM 5
#define MV 65536
int P[VNUM];
int Dist[VNUM];
int Mark[VNUM];
int Matrix[VNUM][VNUM] =
{
{0, 10, MV, 30, 100},
{MV, 0, 50, MV, MV},
{MV, MV, 0, MV, 10},
{MV, MV, 20, 0, 60},
{MV, MV, MV, MV, 0},
};
void Dijkstra(int sv) // O(n*n)
{
int i = 0;
int j = 0;
if( (0 <= sv) && (sv < VNUM) )
{
for(i=0; i<VNUM; i++)
{
Dist[i] = Matrix[sv][i];
P[i] = sv;
Mark[i] = 0;
}
Mark[sv] = 1;
for(i=0; i<VNUM; i++)
{
int min = MV;
int index = -1;
for(j=0; j<VNUM; j++)
{
if( !Mark[j] && (Dist[j] < min) )
{
min = Dist[j];
index = j;
}
}
if( index > -1 )
{
Mark[index] = 1;
}
for(j=0; j<VNUM; j++)
{
if( !Mark[j] && (min + Matrix[index][j] < Dist[j]) )
{
Dist[j] = min + Matrix[index][j];
P[j] = index;
}
}
}
for(i=0; i<VNUM; i++)
{
int p = i;
printf("%d -> %d: %d\n", sv, p, Dist[p]);
do
{
printf("%d <- ", p);
p = P[p];
} while( p != sv );
printf("%d\n", p);
}
}
}
int main(int argc, char *argv[])
{
Dijkstra(0);
return 0;
}
第三:
Floyd 算法基本思想
A 矩阵的意义
第四:
Floyd算法的实现
#include <stdio.h>
#include <stdlib.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define VNUM 5
#define MV 65536
int P[VNUM][VNUM];
int A[VNUM][VNUM];
int Matrix[VNUM][VNUM] =
{
{0, 10, MV, 30, 100},
{MV, 0, 50, MV, MV},
{MV, MV, 0, MV, 10},
{MV, MV, 20, 0, 60},
{MV, MV, MV, MV, 0},
};
void Floyd() // O(n*n*n)
{
int i = 0;
int j = 0;
int k = 0;
for(i=0; i<VNUM; i++)
{
for(j=0; j<VNUM; j++)
{
A[i][j] = Matrix[i][j];
P[i][j] = j;
}
}
for(i=0; i<VNUM; i++)
{
for(j=0; j<VNUM; j++)
{
for(k=0; k<VNUM; k++)
{
if( (A[j][i] + A[i][k]) < A[j][k] )
{
A[j][k] = A[j][i] + A[i][k];
P[j][k] = P[j][i];
}
}
}
}
for(i=0; i<VNUM; i++)
{
for(j=0; j<VNUM; j++)
{
int p = -1;
printf("%d -> %d: %d\n", i, j, A[i][j]);
printf("%d", i);
p = i;
do
{
p = P[p][j];
printf(" -> %d", p);
} while( p != j);
printf("\n");
}
}
}
int main(int argc, char *argv[])
{
Floyd();
return 0;
}
小结:
? Dijkstra 最短路径算法是基于递推的思想设计的
? 未达顶点的最短路径一定是由已达顶点的最短路径求出
? Floyd 最短路径算法只是 Dijkstra最短路径算法的加强 , 其本质还是递推