• Dijkstra求最短路径


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

    Dijkstra算法描述如下:

    (1)用带权的邻接矩阵arcs表示有向图,arcs[i][j]表示弧<vi,vj>上的权值,若<vi,vj>不存在,则置arcs[i][j]=INF。

    vis为已找到从v出发的最短路径的终点集合,它的初始状态为空集。那么,从v出发到图上其余各顶点可能到达的最短路径初值为:

    D[i]=arcs[Vex(G,v)][i],vi属于V

    (2)选择vj,使得D[j]=Min{D[i]|vi属于V-vis},vj就是当前求得的一条从v出发的最短路径的终点。令vis=vis U {j}

    (3)修改从v出发到集合V-vis上任一顶点vk可达的最短路径长度。如果D[j]+arcs[j][k]<D[k],则修改D[k]=D[j]+arcs[j][k]

    (4)重复操作(2)、(3)工n-1次。由此求得从v到图上其余各顶点的最短路径是依路径长度递增的序列

    //Dijkstra:从某个源点到其余各顶点的最短路径
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    #define N  500
    #define INF 0x3f3f3f3f //1061109567 -- 3*(16^7+16^5+16^3+16)+15*(16^6+16^4+16^2+1)
    bool vis[N];//顶点是否已经选入S 
    int p[N];//前驱顶点 
    int dis[N];//最短路径 
    typedef struct graph{
        int vexnum;//顶点数
        int edgenum;//边数 
        int arc[N][N];//邻接矩阵 
    }Graph;
    void CreateGraph(Graph* &);
    void Dijkstra(Graph*);
    void sp(int,int);//最短路
    void CreateGraph(Graph* &G)
    {
        int i,v,w; 
        memset(G->arc,INF,sizeof(G->arc));//初始化为INF
        //printf("%d",G->arc[100][100]);
        printf("有向图的顶点数和边数:");
        scanf("%d%d",&G->vexnum,&G->edgenum);
        printf("有向图顶点序号以及关联权值:");
        for(i=0;i<G->edgenum;i++)
        {
            scanf("%d%d",&v,&w);
            scanf("%d",&G->arc[v][w]);
        }
    }
    void Dijkstra(Graph *G)
    {
        int i,v,w,min;
        memset(vis,false,sizeof(vis)); 
        memset(p,0,G->vexnum);//初始时所有终点的前驱顶点都为始点0
        for(i=1;i<G->vexnum;i++)//最短路径初始化为始点到终点的直接路径长度 
            dis[i] = G->arc[0][i];
        for(i=1;i<G->vexnum;i++)//进行G->vexnum-1次循环,按路径递增每次确定一个顶点 
        {
            min = INF;
            for(w=1;w<G->vexnum;w++) 
            {
                if(!vis[w] && dis[w] <= min)//此处取=号是确保输出 路径时能够显示No Path的顶点 
                {
                    v = w;//v保存当前最小路径对应的终点
                    min = dis[w];
                }
            }
            vis[v] = true;
            sp(v,min);//显示最短路径以及长度 
            for(w=1;w<G->vexnum;w++)//更新当前最短路径以及距离 
            {
                if(!vis[w] && min + G->arc[v][w] < dis[w])
                {
                    dis[w] = min + G->arc[v][w];
                    p[w] = v;
                }
            }
        }
    }
    void sp(int v,int pow)
    {
        if(pow == INF)
        {
            printf("V0--->V%d:No Path
    ",v); 
        }
        else{
            printf("V0-->V%d最短路径长度为:%d,路径如下:
    ",v,pow);
            while(v)//从后往前打印,到始点0结束 
            {
                printf("V%d<-",v);
                v = p[v];
            }
            printf("V0
    ");
        }
    }
    int main()
    {
        Graph *G = (Graph *)malloc(sizeof(Graph));
        CreateGraph(G);
        Dijkstra(G);
        return 0;
    }
     // 6 8
    // 0 2 10
    // 0 4 30
    // 0 5 100
    // 4 5 60
    // 4 3 20
    // 3 5 10
    // 2 3 50
    // 1 2 5
  • 相关阅读:
    8.25
    8.24
    8.23
    8.22
    8.21
    8.20
    8.19
    8.18
    8.17
    8.16
  • 原文地址:https://www.cnblogs.com/emptyCoder/p/5405570.html
Copyright © 2020-2023  润新知