最近做课设的时候用到了这两个算法,于是总结在这里。
Dijkstra是求解一个顶点到其他顶点的最短距离,
算法最简单的实现方法是用一个链表或者数组来存储所有顶点的集合 Q,所以搜索 Q 中最小元素的运算(Extract-Min(Q))只需要线性搜索 Q 中的所有元素。这样的话算法的运行时间是 O(n2)。
求解两点之间最短路径的最短距离,可由Dijkstra算法增加一层循环得到。
Floyd算法是求解两点之间最短路径,思路是:从任意一条单边路径开始,所有两点之间的距离是边的权,或者无穷大,如果两点之间没有边相连。
{
int visit[MAXVEXNUM]; //记录顶点是否访问
int i,j;
//初始化
for(i=0;i<g.n;i++)
{
visit[i] = 0;
if(g.edges[vex][i] == INFINITY)
prev[i] = -1; //prev[i]为第i个顶点的前一个顶点
else
prev[i] = vex;
}
visit[vex] = 1;
for(i=1;i<g.n;i++)
{
int tmp = INFINITY;
int u = vex;
for(j=0;j<g.n; j++) //找最短路径
{
if(!visit[j] && g.edges[vex][j] < tmp)
{
u = j;
tmp = g.edges[vex][j];
}
}
visit[u] = 1;
for(j=0;j<g.n;j++) //通过最短路径依次找次短路径
{
if(!visit[j] && g.edges[u][j] < INFINITY)
{
int newdist = tmp + g.edges[u][j];
if(newdist < g.edges[vex][j])
{
g.edges[vex][j] = newdist;
prev[j] = u;
}
}
}
}
}
void Floyd(MGraph &g,int p[MAXVEXNUM][MAXVEXNUM][MAXVEXNUM]) //弗洛伊德算法
{
int u, v, w, i, j;
//初始化
for(v=0; v<g.n; v++)
for(w=0; w<g.n; w++)
{
for(u=0; u<g.n;u++)
p[v][w][u]=-1; //p为存储路径
if(g.edges[v][w] < INFINITY)
{
p[v][w][0]=v;
p[v][w][1]=w;
}
}
for(u=0; u<g.n; u++)
for(v=0; v<g.n; v++)
for(w=0; w<g.n; w++)
if(g.edges[v][u]+g.edges[u][w] < g.edges[v][w])
{
g.edges[v][w] = g.edges[v][u]+g.edges[u][w];
//更新p,从v到w的路径是从v到u,再从u到w的所有路径
for(i=0; i<g.n; i++)
{
if(p[v][u][i]!=-1)
p[v][w][i]=p[v][u][i];
else
break;
}
for(j=1; j<g.n; j++)//注意:这里j从1开始而不是从0开始,因为从v到u的路径最后一个顶点是u, 而从u到w的路径第一个顶点是u,只需打印u一次即可。
{
if(p[u][w][j]!=-1)
p[v][w][i++]=p[u][w][j];
else
break;
}
}
}