【图】最短路径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 ) <V0,Vi>,d(V0,Vi) <V0,Vi>d(V0,Vi) < V 0 , V i > <V0,Vi> <V0,Vi>弧上的权值
    若不存在 < V 0 , V i > <V0,Vi> <V0,Vi> d ( V 0 , V i ) d(V0,Vi) d(V0,Vi) ∞ ∞
    2.若存在 < V 0 , V i > = d ( V 0 , V i ) <V0,Vi>=d(V0,Vi) <V0,Vi>=d(V0,Vi)那么 < V i , V 0 > = d ( V 0 , V i ) <Vi,V0>=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<stdio.h>
  
#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
Dijkstra算法是一种用于求解最短路径的算法,它是以荷兰计算机科学家Edsger W. Dijkstra的名字命名的。该算法的基本思想是从起点开始,逐步扩展到其他节点,直到到达终点为止。在扩展的过程中,每个节点都会记录到达它的最短路径和距离,直到所有节点都被扩展为止。 在C语言中,可以使用邻接矩阵或邻接表来表示,然后使用Dijkstra算法来求解最短路径。以下是一个简C语言实现: ```c #include <stdio.h> #include <limits.h> #define V 6 // 的顶点数 int minDistance(int dist[], int sptSet[]) { int min = INT_MAX, min_index; for (int v = ; v < V; v++) { if (sptSet[v] == && dist[v] <= min) { min = dist[v]; min_index = v; } } return min_index; } void printSolution(int dist[]) { printf("Vertex \t Distance from Source\n"); for (int i = ; i < V; i++) { printf("%d \t %d\n", i, dist[i]); } } void dijkstra(int graph[V][V], int src) { int dist[V]; int sptSet[V]; for (int i = ; i < V; i++) { dist[i] = INT_MAX; sptSet[i] = ; } dist[src] = ; for (int count = ; count < V - 1; count++) { int u = minDistance(dist, sptSet); sptSet[u] = 1; for (int v = ; v < V; v++) { if (!sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; } } } printSolution(dist); } int main() { int graph[V][V] = { {, 2, 4, , , }, {2, , 1, 4, 2, }, {4, 1, , , 3, }, {, 4, , , 3, 2}, {, 2, 3, 3, , 2}, {, , , 2, 2, } }; dijkstra(graph, ); return ; } ``` 在这个例子中,我们使用邻接矩阵来表示,其中表示两个节点之间没有边,其他数字表示边的权重。我们从节点开始,使用Dijkstra算法来计算到其他节点的最短路径。最后,我们输出每个节点到起点的最短距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值