【图】最短路径Dijkstra算法C语言实现

Dijkstra算法(单源点路径算法)
要求:图中不存在负权值边)

算法步骤如下:
G={V,E}

  1. 初始时令 S = V 0 , T = V − S = S={V0},T=V-S= S=V0,T=VS={其余顶点},T中顶点对应的距离值
    若存在 < V 0 , V i > , d ( V 0 , V i ) ,d(V0,Vi) <V0,Vi>d(V0,Vi) < V 0 , V i > <V0,Vi>弧上的权值
    若不存在 < V 0 , V i > <V0,Vi> d ( V 0 , V i ) d(V0,Vi) d(V0,Vi) ∞ ∞
    2.若存在 < V 0 , V i > = d ( V 0 , V i ) =d(V0,Vi) <V0,Vi>=d(V0,Vi)那么 < V i , V 0 > = d ( V 0 , V i ) =d(V0,Vi) <Vi,V0>=d(V0,Vi)(无向图)
    注:有向图不需要这一步。
  2. 从T中选取一个与S中顶点有关联边且权值最小的顶点W,加入到S中
  3. 对其余T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值缩短,则修改此距离值
    重复上述步骤2、3,直到S 中包含所有顶点,即 W = V i W=Vi W=Vi为止

代码实现:

#include
  
#define SIZE 110  
#define INF 10000000
  
 
int dijkstra(int from, int to,int map[SIZE][SIZE],int n,int m){	//从源点到目标点 
	
    int i,j;  
    int START =from;
    int parent[SIZE];
    int len[SIZE];  	//d[i]表示源点到i这个点的距离 
    int visit[SIZE];  //节点是否被访问 
    for(int i =0;i<SIZE;i++)
       parent[i]=START;
    
    for(i = 1 ; i <= n  ; i ++){	//初始化 
        visit[i] = 0;	//一开始每个点都没被访问 
        len[i] = map[from][i];	//先假设源点到其他点的距离 
    }  
   
    for(i = 1 ; i <= n ; ++i){	//对除源点的每一个点进行最短计算 
        int min = INF;  //记录最小len[i] 
        int pos;  //记录小len[i] 的点 
  
        for(j = 1 ; j <= n ; ++j)
        {	
            if(!visit[j] && min > len[j]){  
                pos = j;  
                min = len[j];  
            }  
        }  
        visit[pos] = 1;  
  
        for(j = 1 ; j <= n ; ++j){
            if(!visit[j] && (len[j] > (len[pos] +map[pos][j])))
            { //如果j节点没有被访问过&&j节点到源节点的最短路径>pos节点到源节点的最短路径+pos节点到j节点的路径  
                len[j] = len[pos] + map[pos][j];	//更新j节点到源节点的最短路径
                parent[j]=pos;	//记录前驱结点
            }  
        }  
    }  
    for(i=1;i<=n;i++)
    {
        if(i!=from)
         printf("the parent of %d is %d \n",i,parent[i]);
    }

    return len[to];
}
void gen(int map[SIZE][SIZE],int vertex_num,int edge_num)
{
    int i,j;
    int k;
    int Ver;
    int start,end;
    
    for(i=0;i<=vertex_num;i++)
    {
        for(j=0;j<=vertex_num;j++)
         map[i][j] = INF;
    }

    for(k=0;k<edge_num;k++)
    {
        scanf("%d%d",&i,&j);
        scanf("%d",&map[i][j]);
        map[j][i] = map[i][j];
    }
}
  
int main () {  
 
    int map[SIZE][SIZE]; 
    int vertex_num; 
    int edge_num;
    int start,end;
    scanf("%d%d",&start,&end);
    scanf("%d%d",&vertex_num,&edge_num);
    
    gen(map,vertex_num,edge_num);

     int ans = dijkstra(start,end,map,vertex_num,edge_num);

     printf("ans = %d",ans);

    return 0;  
}

测试数据:
输入:

1 5//求从1到5的最短路径
6 9//六个顶点,九条边

1 2 7
1 3 9 
1 6 14
2 3 10
2 4 15
5 6 9
3 6 2
4 5 6
3 4 11

后九行相当于

    map[1][2] = 7;	//测试数据 
	map[1][3] = 9;
	map[1][6] = 14;
	map[2][3] = 10;
	map[2][4] = 15;
	map[3][6] = 2;
	map[5][6] = 9;
	map[4][5] = 6;
	map[3][4] = 11;

输出:

the parent of 2 is 1
the parent of 3 is 1
the parent of 4 is 3
the parent of 5 is 6
the parent of 6 is 3
shortest path = 20

你可能感兴趣的:(图,Data_Structure,最短路径)