最短路问题Dijkstra算法

Dijkstra算法可以解决源点到任意点的最短距离并输出最短路径

 

准备:

建立一个距离数组d[ n ],记录每个点到源点的距离是多少

建立一个访问数组v[ n ],记录每个点是否被访问到

建立一个祖先数组p[ n ],记录每个节点的父亲节点是什么

选择一个起始点s

 

执行:

1初始化:所有点到源点的距离都是无穷大

2访问源点,源点到源点的距离自然就变成0,更新与源点相邻的点的距离数组(等于边的权值)

3加入距离最小的点到已访问集合,更新与已访问集合连接的点的距离数组(=min{ 直接距离, 间接距离})以及更新祖先节点数组p[ n ]

4重复步骤3,直到寻找到终点或者访问完所有节点

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 100
#define INF 999
int graph[max][max];
int vertex_num;
int edge_num;
int d[max];
int v[max];
int p[max];

Dijkstra(int s){
    int i,j,k;
    //init part
    for(i=0;i<vertex_num;i++){
        if(graph[s][i]!=0){ //if vertex i next to source vertex s
            d[i]=graph[s][i];//update the distance array
            p[i]=s;
            v[i]=0;
        }else{
            d[i]=INF;
            p[i]=-1;
            v[i]=0;
        }
        
    }
    d[s]=0;
    p[s]=0;
    v[s]=1;
    
    for(i=1;i<vertex_num;i++){
        int min=INF;
        int u;
        for(j=0;j<vertex_num;j++){  //find the shortest distance vertex form all the unvisited vertex
            if(v[j]==0&&d[j]<min){
                min=d[j];   //mini distance
                u=j;        //mini distance vertex u
            }
        }
        v[u]=1; //visit u
        for(k=0;k<vertex_num;k++){
            if(v[k]==0&&graph[u][k]>0&&d[u]+graph[u][k]<d[k]){ //graph[u][k]>0 make sure u and k are connected;
                d[k]=d[u]+graph[u][k];
                p[k]=u;
            }
        }
    }
    printf("Shortest distance form %d:\n",s);
    for(i=0;i<vertex_num;i++){
        printf("%d ",d[i]);
    } 
    printf("\n\n");
}
void show_path(int s,int d){
    int cur=d;
    int tmp[vertex_num];
    
    int i=0;
    while(cur!=s){
        tmp[i++]=cur;
        cur=p[cur];
    }
    tmp[i]=s;
    printf("The shortest path:\n");
    while(i>0){
        printf("%d ->",tmp[i]);
        i--;
    }
    printf("%d",tmp[i]);
} 
int main(){
    int i,j;
    FILE *fin  = fopen ("dij.in", "r");
    FILE *fout = fopen ("dij.out", "w");
    
    char buf[10];
    fgets(buf,10,fin);
    edge_num=atoi(buf);
    
    printf("edge_num:%d\n",edge_num);
    fgets(buf,10,fin);
    vertex_num=atoi(buf);

    printf("vertex_num:%d\n",vertex_num);
    
    for(i=0;i<edge_num;i++){
        int start,end,weight;//start point,end point and the weight of edge
        fgets(buf,10,fin);
        sscanf(buf,"%d %d %d",&start,&end,&weight);
        
        printf("start:%d end:%d weight:%d\n",start,end,weight);
        graph[start][end]=weight;//init the graph matrix no direct
        
    }

    printf("\n");
    printf("Graph matrix:\n");
    for(i=0;i<vertex_num;i++){
        for(j=0;j<vertex_num;j++){
        printf("%-5d",graph[i][j]);
       }
       printf("\n");
    }
    printf("\n");
    Dijkstra(0);
    show_path(0,3);
    return 0;
} 

 

posted @ 2016-12-08 20:50  侯胜滔  阅读(1070)  评论(0编辑  收藏  举报