DS追星(ver.1)

本文介绍了如何使用迪杰斯特拉算法解决含有重复边且边权重可能不同的最短路径问题。通过创建一个图类并实现迪杰斯特拉算法,从起点城市1找到到达终点城市N的最小花费。示例输入和输出展示了算法的正确性,并强调了在处理重复边时需要选取较小权重的做法。
摘要由CSDN通过智能技术生成

题目描述

城市总共有N座。yintama是右京女神的狂热粉,当他得知右京女神将要在城市N举办演唱会的时候,马上开始准备动身前往城市N。原本他可以直接乘飞机直达城市N,然而贫穷使他屈服,他必须选择总花费最少的那条路径。设总共有N座城市(2<=N<=1000),城市编号分别为1,2,3......N。M条航线(1<=M<=2000),每条航线连接两座城市,相互可以到达(无向的)。yintama目前在身在城市1,求最后yintama参加右京女神演唱会所需要的最少花费。(PS:重边考虑一下?)

输入

有多组输入。

第一行输入一个N、M,代表城市的总数,以及航线的总数。

接下来M行,每行输入三个数字u v w,代表城市u、v之间存在航线,机票花费为w。

输出

每行输出一个数,代表yintama参加右京女神演唱会所需的最少花费。

输入样例1

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

输出样例1

90

NOTICE:这个题就是最短路径算法,这里采用迪杰斯特拉算法,基本照搬,不多提;唯一需要注意的就是,输入可能会有两条一样的航线但却有不同的票价,我们要选择较小的票价作为矩阵的权值即可。

#include <iostream>
using namespace std;
#define MAX 65535

class Graph
{
private:
	int vertexnum;
	int edgenum;
	int** Matrix;
public:
	Graph(int vm,int em)
	{
		vertexnum = vm;
		edgenum = em;
		Matrix = new int* [vertexnum];
		for (int i = 0; i < vertexnum; i++)
			Matrix[i] = new int[vertexnum];
		for (int i = 0; i < vertexnum; i++)
		{
			for (int j = 0; j < vertexnum; j++)
			{
				Matrix[i][j] = MAX;
			}
		}
		for (int i = 0; i < edgenum; i++)
		{
			int a, b, w;
			cin >> a >> b >> w;
			
			//考虑可能会出现同一条航线两种票价,选择较小的
			if (w < Matrix[a - 1][b - 1])
			{
				Matrix[a - 1][b - 1] = w;
				Matrix[b - 1][a - 1] = w;
			}
		}
	}
	void Dijkstra()
	{
		int* D = new int[vertexnum];
		int* final = new int[vertexnum];
		int flag;

		//初始化
		flag = 0;
		for (int i = 0; i < vertexnum; i++)
		{
			D[i] = Matrix[flag][i];
			final[i] = 0;
		}
		final[flag] = 1;

		//循环
		for (int i = 0; i < vertexnum - 1; i++)
		{
			//找flag
			int tmp = MAX;
			for (int j = 0; j < vertexnum; j++)
			{
				if (final[j] == 0 && D[j] < tmp)
				{
					tmp = D[j];
					flag = j;
				}
			}
			final[flag] = 1;

			//更新D
			for (int j = 0; j < vertexnum; j++)
			{
				if (final[j] == 0 && D[flag] + Matrix[flag][j] < D[j])
				{
					D[j] = D[flag] + Matrix[flag][j];
				}
			}
		}

		//输出
		cout << D[vertexnum - 1] << endl;
	}
};

int main()
{
	int vm, em;
	while (cin >> vm >> em)
	{
		Graph g(vm, em);
		g.Dijkstra();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值