数学建模:最短路径问题

 一、问题介绍

在一个无向图内,确定起点与其余各点的最短路径与距离

二、代码

运用迪杰思特拉算法

1.先初始化最短路径数组dis[]与前驱数组path[];

2.初始化起点的距离

3.循环多次两个循环:第一个for循环确定下一个最短路径的结点,第二个for循环更新每次找到结点后其他结点的最短路径,并将其保存到dis数组内。最后dis数组保存的就是所有点位距离起点的最短路径。

#include <iostream>
#define Max 503
#define INF 0xcffffff

using namespace std;

typedef struct AMGraph
{
	int vex = 6, arc = 9;
	int arcs[7][7] = { {0, 0, 0 , 0, 0, 0, 0},
					{0, INF, 1, 12, INF, INF, INF},
					{0, 1, INF, 9, 3, INF, INF},
					{0, 12, 9, INF, 4, 5, INF},
					{0, INF, 3, 4, INF, 13, 15},
					{0, INF, INF, 5, 13, INF, 4},
					{0, INF, INF, INF, 15, 4, INF} };
};

//dis保存最短路径,path保存最短路径的前驱结点
int dis[Max], path[Max];
bool book[Max];

void Dijkstra(AMGraph &G)
{
	//初始化最短路径数组dis和前驱数组path
	for (int i = 1; i <= G.vex; i++)
	{
		dis[i] = G.arcs[1][i];
		path[i] = dis[i] < INF ? 1 : -1;
	}

	//将起点归入最短路径集合
	book[1] = true;

	//初始化起点距离
	dis[1] = 0;

	for (int i = 2; i <= G.vex; i++)
	{
		int mins = INF, u = 1;
		for (int j = 1; j <= G.vex; j++)
		{
			//找出未加入集合的最短路径
			if (!book[j] && dis[j] < mins)
			{
				mins = dis[j];
				u = j;
			}
		}
		book[u] = true;
		for (int j = 1; j <= G.vex; j++)
		{
			//遍历其他点位更新其最短路径
			if (!book[j] && dis[j] > dis[u] + G.arcs[u][j])
			{
				dis[j] = dis[u] + G.arcs[u][j];
				path[j] = u;
			}
		}
	}
}

//输入各点位的邻接矩阵
void putin(AMGraph &G)
{
	/*cin >> G.vex >> G.arc;
	for (int i = 1; i < G.vex; i++)
	{
		for (int j = 1; j < G.vex; j++)
		{
			G.arcs[i][j] = INF;
		}
	}
	
	for (int i = 1; i < G.vex; i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		G.arcs[u][v] = w;
	}*/
	
							
}

//输出各点位到起点的最短路径的值
void putout(AMGraph &G)
{
	for (int i = 1; i <= G.vex; i++)
	{
		cout << dis[i] << "  ";
	}
}

//找到点位的最短路径
void find(AMGraph &G)
{
	int x;
	cin >> x;
	while (x)
	{
		cout << x << "->";
		if (path[x] == -1)
			break;
		x = path[x];
	}
	
}

int main()
{
	AMGraph G;
	// putin(G);
	Dijkstra(G);
	putout(G);
	find(G);
	return 0;
}

三、运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值