码迷,mamicode.com
首页 > 其他好文 > 详细

Dijkstra求最短路径

时间:2016-04-18 20:26:34      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

单源点的最短路径问题:给定带权有向图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\n",v); 
    }
    else{
        printf("V0-->V%d最短路径长度为:%d,路径如下:\n",v,pow);
        while(v)//从后往前打印,到始点0结束 
        {
            printf("V%d<-",v);
            v = p[v];
        }
        printf("V0\n");
    }
}
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

 

Dijkstra求最短路径

标签:

原文地址:http://www.cnblogs.com/520xiuge/p/5405570.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!