【2024.2.27练习】[2022 国 B] 出差

题目描述


题目分析

单源最短路径问题。由数据规模可知,使用Bellman-Ford算法可能超时,且没有负边,故使用Dijksra算法。为了便于计算最短路径,将隔离时间加入到边的权值中。使用Map容器储存最小边,便于存取。


我的代码

在C++中,如果使用std::map容器,其默认的排序方式是按照key的升序进行排序。如果key是pair类型,那么默认情况下会按照pair的字典序进行排序。也就是说,会先比较第一个元素,如果第一个元素相等,则比较第二个元素。

例如,对于std::map<std::pair<int, int>, int>,会按照pair的第一个元素升序排序,如果第一个元素相等,则按照第二个元素升序排序。

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int MAX_V = 1002;
const int MAX_E = 10002;
int cost[MAX_V][MAX_V]; //cost[u][v]表示边e=(u,v)的权值
int d[MAX_V]; //记录最短距离
int value[MAX_V]; //记录隔离时间
map<pair<int, int>, int> M; //堆存放最小边
map<pair<int, int>, int>::iterator it; //迭代器
int v;
int e;
int main() {
	/*初始化*/
	cin >> v >> e;
	for (int i = 0; i < MAX_V; i++)
	{
		for (int j = 0; j < MAX_V; j++) {
			cost[i][j] = 0x3f3f3f3f;
		}
	}
	for (int i = 1; i <= v; i++)
	{
		cin >> value[i];
		if (i == v) {
			value[i] = 0; //最后一个城市不用计算隔离时间
		}
		d[i] = 0x3f3f3f3f;
		d[1] = 0;
		pair<int, int> P(d[i], i);
		M.insert(pair<pair<int, int>, int>(P, i));
	}
	for (int i = 1; i <= e; i++)
	{
		int s;
		int t;
		int lenth;
		cin >> s >> t >> lenth;
		cost[s][t] = lenth + value[t];
		cost[t][s] = lenth + value[s];
	}

	/*Dijkstra算法*/
	while (!M.empty()) {
		it = M.begin();
		//int lenth = (*it).first;
		int s = (*it).second; //获取当前搜索点
		it = M.erase(it);
		for (int i = 1; i <= v; i++)
		{
			if (d[i] > d[s] + cost[s][i]) {
				pair<int, int> P(d[i], i);
				M.erase(P);//从容器中删除
				d[i] = d[s] + cost[s][i];
				pair<int, int> P2(d[i], i);
				M.insert(pair<pair<int, int>, int>(P2, i));//覆盖原最短路径
			}
		}
	}
	/*获取结果*/
	cout << d[v];
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值