图的最短路径

求最短路径常用算法DijkstraFloyd

1、Dijksta算法
a、首先标记起点。
b、然后循环遍历所有点,如果这个点没被标记,距起点较近,那么用一个变量u记录该点,重复这个过程,保证u点为距离起点最近而且没有被标记的点。
c、标记u点。
d、重新计算u的未标记邻接点v距离起点的最近距离。需要比较该邻接点v距起点的距离与u与起点距离加上边u,v的权重的大小。取较小者。
f、重复b c d过程,直到所有点标记完毕。

#define N 6 // 定义点数
#define M 32767 // 无穷大,两点间没边

int a[N][N]; // 邻接矩阵, a[i][i] = M

int label[N]; // 标记
int dist[N]; // 记录每个点距离起点最近距离
int prev[N]; // 记录最近距离上该点的上一个点

void dijkstra(int start)
{
    // 初始化label dist prev
    int i;
    for(i=0; i<N; i++)
    {
        label[i] = 0;
        dist[i] = a[start][i]; // dist初始为邻接矩阵值
        prev[i] = (dist[i] < M) ? start : -1;
    }
    label[start] = 1; // 标记起点

    int j, u, min;
    for(i=0; i<N-1; i++) // 循环标记,起点已标,只需循环N-1
    {
        min = M;
        u = -1;
        for(j=0; j<N; j++)
        {
            if(label[j] == 0 && dist[j] < min)
            {
                min = dist[j];
                u = j;
            }
        }
        if(u != -1)
        {
            label[u] = 1; // 标记u
            for(j=0; j<N; j++)
            {
                // 更新dist prev
                if(a[u][j] < M) {
                    if(label[j] == 0 && 
                    a[u][j] + dist[u] < dist[j])
                    {
                        dist[j] = a[u][j] + dist[u];
                        prev[j] = u; 
                    }
                }
            }
        }
    }
}

2、Floyd算法
可以求解出任意两个顶点间的最短路径长度,求不出路径。
a、构建邻接矩阵a,a[i][i]=0,其它没边的为无穷。
b、三重循环,不断在i, j之间添加经过点,若使距离变短,则保留该经过点。因为i, j, k会出现重复,所以a[i][i] = 0而不是无穷来避免a[i][i]被修改产生环路。

#define N 6 // 定义点数

int a[N][N]; // 邻接矩阵

void floyd()
{
    int i, j, k;
    for(k=0; k<N; k++)
        for(i=0; i<N; i++)
            for(j=0; j<N; j++)
                if(a[i][j] > a[i][k] + a[k][j])
                {
                    a[i][j] = a[i][k] + a[k][j];
                }
}

你可能感兴趣的:(数据结构,最短路径,图)