迪杰斯特拉最小生成树

#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
const int maxn = 1010;
#define inf 0x1f1f1f1f
using namespace std;

//struct Edges {
//	int start,end, w;  //边的起点,终点,权值
//};
struct mygraph{
	// vexs[maxn];  //顶点数组
	int vexnums;  //顶点个数
	int edgenums;  //边数
	int matrix[maxn][maxn];  //邻接矩阵
}mat;
void Dijkstra(int u, int v)
{
	int val = u;  //记录上一个节点
	int pathmin[maxn];  //存放u节点到各节点之间的最短路径
	int vis[maxn];  //存储最短路径的上一个节点,以便于等会输出路径
	int visited[maxn];  //记录节点是非被访问过
	memset(vis, -1, sizeof(vis));
	//vis[u] = -1;  //这里设置一个不可能的值作为等会输出的出口
	memset(visited, 0, sizeof(visited));
	visited[u] = 1;  //将起始点设置为已访问
	for (int i = 0; i < mat.vexnums; ++i)
	{
		pathmin[i] = mat.matrix[u][i];  //将u源点与其他各顶点的距离放入pathmin
	}
	pathmin[u] = 0;  //自己到自己距离为0

	for (int i = 0; i < mat.vexnums; ++i)
	{
		int minnum = inf, k;
		for (int j = 0; j < mat.vexnums; ++j)  //找到起始点u到其他节点的最短路径
		{
			if (visited[j]!=1&&pathmin[j] < minnum) {
				k = j;
				minnum = pathmin[j];
				if(val==u) vis[j] = val;  //记录起点为原点
			}
		}
		visited[k] = 1;
		val = k;
		for (int j = 0; j < mat.vexnums; ++j)
		{
			if (!visited[j] && minnum + mat.matrix[k][j] < pathmin[j])
			{
				pathmin[j] = minnum + mat.matrix[k][j];
				vis[j] = val;  //记录上一个节点
			}
		}
	}
	//输出最短路径
	cout << "从" << u+1 << "到" << v+1 << "的最短路径长度为:" << pathmin[v] << "\n路径为:";
	vector<int> path;
	while (vis[v] != -1)
	{
		path.push_back(v + 1);
		v = vis[v];
	}
	path.push_back(u + 1);
	reverse(path.begin(), path.end());
	for (int i = 0; i < path.size(); i++)
	{
		if (i == 0) cout << path[i];
		else cout << " -> " << path[i];
	}
}
int main()
{
	int n, m, u, v; cin >> n >> m >> u >> v;  //输入顶点数与边数,和需要求的两顶点的最小距离
	mat.vexnums = n;
	mat.edgenums = m;
	for (int i = 0; i < maxn; ++i)
	{
		for (int j = 0; j < maxn; ++j)
			mat.matrix[i][j] = inf;
	}
	for (int i = 0; i < m; ++i)  //初始化图
	{
		int x, y, w;
		cin >> x >> y >> w;
		mat.matrix[x-1][y-1] = w;
		mat.matrix[y-1][x-1] = w;
	}
	Dijkstra(u-1, v-1);
	system("pause");
	return 0;
}
//样例:
//5 7 1 5
//1 4 2
//2 3 5
//1 2 3
//1 3 7
//3 4 4
//4 5 1
//3 5 6
//从1到5的最短路径长度为:3
//	路径为 : 1 -> 4 -> 5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值