最短路径

来源:互联网 发布:java 时间日历控件 编辑:程序博客网 时间:2024/05/17 07:47

1. 问题描述

单源点最短路径:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径。


2. 迪杰斯特拉(Dijkstra)算法

迪杰斯特拉算法按照最短路径递增的次序产生最短路径。具体参见数据结构。


3. 算法实现

采用邻接矩阵作为其存储结构。

void dijkstra(MGraph *G, int v0, int (*P)[G->vexnum], int D[]){    /**若P[v][w]=1, 则w是从v0到v当前求得最短路径上的顶点*/    int i, v, w, min, final[G->vexnum];    v0 = v0 - 1;    memset(final, 0, sizeof(final));         //false:0  true:1    for (v = 0;v < G->vexnum;v++) {        D[v] = G->arcs[v0][v];               //D[i]表示当前所找到的从始点v到每个终点vi的最短路径的长度        memset(P[v], 0, sizeof(int) * G->vexnum);    //set empty path        if (D[v] < INT_MAX) {            P[v][v0] = 1;            P[v][v] = 1;            /** debugging */            //printf("P[%d][%d] = 1, p[%d][%d] = 1\n", v, v0,v,v);        }    } //for    D[v0] = 0;    final[v0] = 1;    for (i = 1;i < G->vexnum;i++) {        min = INT_MAX;        for (w = 0;w < G->vexnum;w++)               // find the current min            if (final[w] == 0)                if (D[w] < min) {                    v = w;                    min = D[w];                }        final[v] = 1;   //the current minist path: V0...Vv        for (w = 0;w < G->vexnum;w++)   {           // update the current path and its cost            /** debugging */            //printf("D[%d]=%d, G.arcs[%d][%d]=%d\n", w, D[w],v, w, G->arcs[v][w]);            if (final[w] ==0 && (G->arcs[v][w] < INT_MAX) && (min + G->arcs[v][w]) < D[w]) {                /* when G->arcs[v][w] is equal to INT_MAX, (min + G->arcs[v][w]) overflows,                *  its value less than zero                */                D[w] = min + G->arcs[v][w];                //P[w] = P[v];                memcpy(P[w], P[v], sizeof(P[v]));                /*                for (j = 0;j < G->vexnum;j++)                    P[w][j] = P[v][j];                */                *(P[w] + w) = 1;            }// if        }    } //for    /** debugging */    for (i = 0;i < G->vexnum;i++)        printf("min{V%d->V%d} = %d\n", v0, i + 1, D[i]);    printf("\n");    printf("path:\n");    for (v = 0;v < G->vexnum;v++){        for (w = 0;w < G->vexnum;w++)            printf("P[%d][%d]=%d,", v, w, P[v][w]);        printf("\n");    }}/**61 3 101 5 301 6 1002 3 53 4 504 6 105 4 205 6 600 0 0*/

4. 测试输出



5. 时间复杂度

设n为顶点树、数,算法时间复杂度为O(n^2)。