最短路径

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");
    }

}

/**
6
1 3 10
1 5 30
1 6 100
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60
0 0 0
*/

4. 测试输出



5. 时间复杂度

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值