【数据结构】算法7.15 Dijkstra算法 单源点最短路径

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAX_VERTEX_NUM 20  //最大顶点个数
#define  INFINITY 65535   //最大值∞

typedef int Status;
typedef enum {DG,DN,UDG,UDN} GraphKind;   //{有向图,有向网,无向图,无向网}

typedef struct
{
    int vexs[MAX_VERTEX_NUM];  //顶点向量
    int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  //邻接矩阵
    int vexnum,arcnum;  //图的当前顶点数和弧数
    GraphKind kind;  //图的种类标志
}MGraph;

typedef int PathMatrix;
typedef int ShortPathTable;

/*******************************声明部分****************************************/
Status CreateDN(MGraph *G);
//构造有向网
int LocateVex(MGraph G,int v);
//确定v在G中的位置
Status ShortestPath_DIJ(MGraph G,int v0,PathMatrix *p,ShortPathTable *D);
//用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及其带权长度D[v]

/*******************************函数部分****************************************/
Status CreateDN(MGraph *G)
{
    printf("\n构造有向网\n");
    int i,j,k; //i,j,k用于计数
    int w;  //权重
    int v1,v2;  //弧头,弧尾

 /*   printf("请输入顶点个数:");
    scanf("%d",&(*G).vexnum);
    printf("请输入弧个数:");
    scanf("%d",&(*G).arcnum);
    //假定该图不含其他信息
    int IncInfo = 0;

    for(i = 0;i<(*G).vexnum;i++){  //构造顶点向量
        printf("请输入G.vexs[%d] = ",i);
        scanf("%d",&(*G).vexs[i]);
    } //for

    for(i = 0;i<(*G).vexnum;i++)  //初始化邻接矩阵
        for(j = 0;j<(*G).vexnum;j++)
            (*G).arcs[i][j] = INFINITY;  //有向网

    for(k = 0;k<(*G).arcnum;k++){  //构造邻接矩阵
        printf("请输入弧头(初始点):");  //输入一条弧的始点和终点
        scanf("%d",&v1);
        printf("请输入弧尾(终端点):");
        scanf("%d",&v2);
        printf("请输入权重:");
        scanf("%d",&w);

        i = LocateVex(*G,v1);
        j = LocateVex(*G,v2);

        if(i>=0 && j>=0)
            (*G).arcs[i][j] = w;  //置<v1,v2>的对称弧<v2,v1>
    */
    (*G).vexnum = 6;
    (*G).arcnum = 8;
    for(i = 0;i<(*G).vexnum;i++)
        (*G).vexs[i] = i;
    for(i = 0;i<(*G).vexnum;i++)
        for(j = 0;j<(*G).vexnum;j++)
            (*G).arcs[i][j] = INFINITY;

    (*G).arcs[0][2] = 10;
    (*G).arcs[1][2] = 5;
    (*G).arcs[2][3] = 50;
    (*G).arcs[4][3] = 20;
    (*G).arcs[0][4] = 30;
    (*G).arcs[0][5] = 100;
    (*G).arcs[3][5] = 10;
    (*G).arcs[4][5] = 60;

    return OK;
}

int LocateVex(MGraph G,int v)
{
    int ct;
    for(ct = 0;ct < G.vexnum;ct++)
        if(G.vexs[ct] == v)
            return ct;
    return -1;
}

Status ShortestPath_DIJ(MGraph G,int v0,PathMatrix *p,ShortPathTable *D)
{
    int v,w,i,min,j;
    int final[MAX_VERTEX_NUM];


    for(v = 0;v<G.vexnum;v++){
        final[v] = 0;
        D[v] = G.arcs[v0][v];
        p[v] = -1;
    }//for

    D[v0] = 0;
    final[v0] = 1;  //初始化,v0顶点属于S集

    //开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集
    for(i = 0;i<G.vexnum;++i){   //其余G.vexnum-1个顶点
        min =INFINITY;     //当前所知离v0顶点的最近距离
        for(w = 0;w < G.vexnum;++w)
            if(!final[w])
                if(D[w]<min){   //w顶点在V-S中
                    v = w;
                    min = D[w];   //w顶点离v0顶点更近
                }//if

        final[v] = 1;  //离v0顶点最近的v加入S集

        for(w = 0;w<G.vexnum;w++)   //更新当前最短路径及距离
            if(!final[w] && (min+G.arcs[v][w]<D[w])){  //修改D[w]和P[w],w属于V-S
                D[w] = min+G.arcs[v][w];
                for(j = 1;j<G.vexnum;j++)
                    p[w] = v;
            }//if
    }//for
}


/*******************************主函数部分**************************************/

int main()
{
    MGraph G;
    ShortPathTable D[MAX_VERTEX_NUM];
    PathMatrix P[MAX_VERTEX_NUM];
    int v0 = 0,i,j;

    CreateDN(&G);
    ShortestPath_DIJ(G,v0,P,D);

    printf("\n最短路径倒叙如下:\n");
    for(i = 0;i<G.vexnum;i++){
        printf("v%d - v%d : ",v0,i);
        j = i;
        printf("v%d",i);

        while(P[j] != -1){
            printf("<-");
            printf("v%d",P[j]);
            j = P[j];
        }
        printf("<-v0");
        printf("\n");
    }

    printf("\n源点到各顶点的最短路径长度为:\n");
    for(i = 0;i<G.vexnum;i++){
        if(D[i] != INFINITY)
            printf("v%d-v%d : %d \n",G.vexs[0],G.vexs[i],D[i]);
        else
            printf("v%d-v%d : ∞ \n",G.vexs[0],G.vexs[i]);
    }


    return 0;
}



这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值