题目:单源最短路径问题的问题提出是,计算带权有向图G =(V, E)中一个点(源点)到其余各顶点的最短路径长度,如下图所示。设源点为顶点1,采用Dijkstra算法求下图中源V0为到其余各顶点的最短路径。
代码实现:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define INF 100//距离无穷大,定义100是怕栈溢出
#define MAX_SIZE 100//数组容量
int dist[MAX_SIZE];//距离数组
int path[MAX_SIZE];//路径数组
int visited[MAX_SIZE];//访问数组 未访问0 已访问1
struct Graph
{
int vertex[MAX_SIZE];//顶点数组
int arc[MAX_SIZE][MAX_SIZE];//边数组
int vertexnum, arcnum;//顶点和边的个数
};
void GraphCreate(struct Graph* graph)//用邻接矩阵表示图,初始化和创建
{
for (int i = 1; i <= graph->vertexnum; i++)//初始化
for (int j = 1; j <= graph->vertexnum; j++)
graph->arc[i][j] = INF;//这里初始化为无穷大是方便初始化路径数组
int a = 0, b = 0, w = 0;//我有初始化的好习惯~
for (int i = 1; i <= graph->arcnum; i++)//创建
{
printf("请输入有边依附的两个顶点的编号以及权重:\n");
scanf("%d%d%d", &a, &b, &w);
graph->arc[a][b] = graph->arc[b][a] = w;
}
}
void Dijsktra(struct Graph* graph, int from, int to)
{
for (int i = 1; i <= graph->vertexnum; i++)//初始化数组
{
dist[i] = graph->arc[from][i];//距离初始化为源点到其他各顶点的距离
visited[i] = 0;//默认都没有访问过
}
for (int i = 1; i <= graph->vertexnum; i++)
{
if (dist[i] == INF)
path[i] = -1;//如果没有边连接就初始化为-1
else
path[i] = from;
}
for (int i = 1; i < graph->vertexnum; i++)//除源点外去最小的路径
{
int min = 100;
int pos = -1;//记录找到的下标
for (int j = 1; j <= graph->vertexnum; j++)
{
if (!visited[j] && dist[j] < min)//如果未访问并且有更小的,那么更新
{
min = dist[j];
pos = j;
}
}
visited[pos] = 1;//找到了就标记已经访问
for (int j = 1; j <= graph->vertexnum; j++)//更新dist数组
{
if (!visited[j] && dist[pos] + graph->arc[pos][j] < dist[j])
{ //dist[pos]是前面一个结点到该结点的距离,are[pos][j]是该结点到下一个结点的距离
//dist[i]是前面一个结点到下一个结点的距离 可以理解为两条折线和一条直线的距离去比较长短
dist[j] = dist[pos] + graph->arc[pos][j];
path[j] = pos;
}
}
}
printf("最短路径为:%d\n",dist[to]);
}
void PrintPath(int path[], int from, int to)//打印路径 我用递归感觉更方便,csdn好多堆栈来写!!
{
if (path[to] != from)
{
PrintPath(path, from, path[to]);
printf("%d->", path[to]);
}
else
printf("%d->", path[to]);
}
int main()
{
struct Graph graph;
printf("请分别输入顶点和边的个数:\n");
scanf("%d%d",&graph.vertexnum, &graph.arcnum);
GraphCreate(&graph);
int from = 0,to = 0;
printf("请输入起点和终点:\n");
scanf("%d%d", &from, &to);
Dijsktra(&graph, from, to);
PrintPath(path, from, to);
printf("%d", to); //因为路径数组里面只有路径,没有终点!!
return 0;
}
运行结果: