YNZH's Blog

单源点求图最短路径之迪杰斯特拉最短路径算法
前提:途中不能存在负权值
目的:求出图中源点到其他所有顶点的最短路径。
思想:可以理解为一种贪心算法,从单源点出发,层层向外扩展,直到终点。

input

edge.txt

这里简单的以一个无向图为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0 2 700
0 4 1000
0 7 300
0 5 600
1 2 1000
1 8 500
1 6 1000
2 3 400
2 8 600
3 4 300
3 6 400
4 5 600
5 6 500
6 8 100
7 8 1000

C语言实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#define MAX_VEX 9
#define INFINITY 9999
int g[MAX_VEX][MAX_VEX] = {INFINITY};
void init()
{
memset(g,INFINITY,sizeof(g));
FILE * fp = fopen("edge.txt","r");
if(!fp)
{
printf("edge.txt not exists!\n");
return ;
}
while(!feof(fp))
{
int l,r,val;
fscanf(fp,"%d",&l);
fscanf(fp,"%d",&r);
fscanf(fp,"%d",&val);
g[l][r] = val;
g[r][l] = val;
}
int i,j;
for(i = 0;i<MAX_VEX;i++)
{
for(j = 0;j<MAX_VEX;j++)
{
printf("g[%d][%d]=%d ",i,j,g[i][j]);
}
printf("\n");
}
fclose(fp);
}
//贪心法则
void DIJ(int v0,int dst)
{
int final[MAX_VEX] = {0};
int path[MAX_VEX] = {0}; //保存路径 Path[i]表示到i最短路径的上一个节点
int dis[MAX_VEX] = {0}; //保存v0到i的距离贪心改变
int n = MAX_VEX;
int i,k,tmp;
for(i =0;i<n;i++)
{
g[i][i] = 0;
if(g[v0][i]==0 || g[v0][i] ==INFINITY)
path[i] = 0;
else
path[i] = v0;
dis[i] = g[v0][i];
}


for(i=0;i<n;i++)
{
int min = INFINITY*2;
if(i==v0)
continue;
//每次选出一个到源点的最小值
for(k=0;k<n;k++)
{
if(!final[k] && dis[k] <min)
{
min = dis[k];
tmp = k;
}
}
final[tmp] = 1;

//利用已经求出的最小值更新路径 更新其他路径的距离
for(k=0;k<n;k++)
{
if(!final[k] && min+g[tmp][k] <dis[k])
{
dis[k] = min +g[tmp][k];
path[k] = tmp;
}
}
}

//print src to dst path
//将最短路径保存到trace数组中此处为逆序保存 最后在逆序输出即为正确顺序
int trace[MAX_VEX];
int tot= 0;
trace[tot++] = dst;
int temp = path[dst];
while(temp!=v0)

{
trace[tot++] = temp;
temp = path[temp];
}
trace[tot] = v0;
for(k = tot;k>=0;tot--)
{
if(trace[tot]==dst)
{
printf("%d\n",dst);
break;
}
else
{
printf("%d->",trace[tot]);
}
}

}

int main()
{
init();
DIJ(0,3);
return 0;
}

 评论


博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站使用 Material X 作为主题 , 总访问量为 次 。
载入天数...载入时分秒...