最短路径djikstra算法

算法好难,费了九牛二虎之力,一点点照着敲了下来,方便理解。

#include<iostream>
using namespace std;
#include<queue>
typedef int vertextype;		//顶点类型
typedef int edgetype;		//边上的权值类型
#define max 100			//最大顶点数
#define INF 65535		//65535代表正无穷

class mgraph
{
public:
	vertextype vexs[max];	//顶点表
	edgetype arc[max][max];//邻接矩阵,可看做边表
	int numvertexes, numedges;//顶点个数,边的个数
};

void createmgraph(mgraph &G)
{
	//cout << "请输入顶点数和边数" << endl;
	cin >> G.numvertexes >> G.numedges;
	for (int i = 0; i < G.numvertexes; i++)
		for (int j = 0; j < G.numvertexes; j++)
			G.arc[i][j] = INF;		//邻接矩阵初始化
	int i, j, w = 0;
	//cout << "输入顶点信息,建立顶点表" << endl;
	for (int k = 0; k < G.numvertexes; k++)		//建立顶点表
		cin >> G.vexs[k];
	for (int m = 0; m < G.numedges; m++)		//建立numedges条边
	{
		//cout << "输入边(Vi,Vj)的上标i,下标j,和权重w " << endl;
		cin >> i >> j >> w;
		G.arc[i][j] = w;
		G.arc[j][i] = G.arc[i][j];	//无向图,矩阵对称
	}
}


void dijkstra(mgraph &G, int v0)		//v0 传入的开始点		
{
	int dist[max];		//dist[] 存放当前起点到其余各点的最短路径的长度
	int path[max];		//path[] 存最短路径下标的数组 , 存的是最短路径下,前一个顶点  例如 psth[1]=0 顶点1的前一个顶点为顶点0

	int set[max];		//标志数组 ,选入最短路径后标记为1
	int min, k;

	for (int i = 0; i < G.numvertexes; i++)//初始化
	{
		dist[i] = G.arc[v0][i];		//传入dist数组初值,初始是点v0到各点的距离
		set[i] = 0;			//初始化set[]
		//if (G.arc[v0][i] < INF)		//如果v0到某一顶点距离小于 INF,就将v0作为最短路径下顶点i的前一个顶点
		//	path[i] = v0;
		//else
		//	path[i] = -1;		//没有前一个结点
	}
	set[v0] = 1; path[v0] = -1;	//开始点已传入,标记为1,且没有头结点
	dist[v0] = 0;		//v0到v0的距离为0

	for (int i = 0; i < G.numvertexes ; i++)
	{
		min = INF;	//初始化min
		for (int j = 0; j < G.numvertexes; j++)	//通过这个循环,挑选出当前没有被并入的顶点中,离起点最近的顶点。
		{
			if (!set[j] && dist[j] < min)
			{
				k = j;		//保存当前最近下标顶点,不断循环,最终k为最近顶点
				min = dist[j];
			}
		}
		set[k] = 1;		//将最近的顶点并入最短路径中

		for (int j = 0; j < G.numvertexes; j++)	//对dist,path数组不断更新
		{
			if (!set[j] && dist[k] + G.arc[k][j] < dist[j])		//j,当前要检测的顶点,dist[j] 起点到j的最小路径长度     k,上一步并入的顶,dist[k]=min 起点到j的最小路径长度
			{													//‘由起到直接到当前检测的点’是否大于‘由起点到上一步所并入的那个顶点 + 再由该顶点到当前顶点的距离’
				dist[j] = dist[k] + G.arc[k][j];
				path[j] = k;
			}
		}
	}
	// 打印dijkstra最短路径的结果
	cout << "顶点" << v0 << "到各顶点的最短路径为" << endl;
	for (int i = 0; i < G.numvertexes; i++)
		cout << G.vexs[v0] << "->" << G.vexs[i] << "  " << dist[i] << endl;
	
	
}


int main()
{
	mgraph g;
	createmgraph(g);
	dijkstra(g, 0);
	
	system("pause");
	return 0;

}

/*
5 6
0 1 2 3 4
0 1 9
0 2 2
0 4 6
1 2 3
2 3 5
3 4 1
9 16
0 1 2 3 4 5 6 7 8
0 1 1
0 2 5
1 2 3
1 4 5
1 3 7
2 4 1
2 5 7
3 4 2
3 6 3
4 6 9
4 5 3
4 7 9
5 7 5
6 7 2
6 8 7
7 8 4
*/

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值