蓝桥杯2022年第十三届决赛真题-出差

题目 2695: 蓝桥杯2022年第十三届决赛真题-出差
时间限制: 1s 内存限制: 256MB 提交: 1675 解决: 558
题目描述
A 国有 N 个城市,编号为 1 . . . N。小明是编号为 1 的城市中一家公司的员工,今天突然接到了上级通知需要去编号为 N 的城市出差。

由于疫情原因,很多直达的交通方式暂时关闭,小明无法乘坐飞机直接从城市 1 到达城市 N,需要通过其他城市进行陆路交通中转。小明通过交通信息网,查询到了 M 条城市之间仍然还开通的路线信息以及每一条路线需要花费的时间。

同样由于疫情原因,小明到达一个城市后需要隔离观察一段时间才能离开该城市前往其他城市。通过网络,小明也查询到了各个城市的隔离信息。(由于小明之前在城市 1,因此可以直接离开城市 1,不需要隔离)

由于上级要求,小明希望能够尽快赶到城市 N,因此他求助于你,希望你能帮他规划一条路线,能够在最短时间内到达城市 N。

输入格式
第 1 行:两个正整数 N, M, N 表示 A 国的城市数量,M 表示未关闭的路线数量

第 2 行:N 个正整数,第 i 个整数 Ci 表示到达编号为 i 的城市后需要隔离的时间

第 3 . . . M + 2 行:每行 3 个正整数,u, v, c,表示有一条城市 u 到城市 v 的双向路线仍然开通着,通过该路线的时间为 c

输出格式
第 1 行:1 个正整数,表示小明从城市 1 出发到达城市 N 的最短时间(到达城市 N,不需要计算城市 N 的隔离时间)
样例输入
4 4
5 7 3 4
1 2 4
1 3 5
2 4 3
3 4 5
样例输出
13
提示
在这里插入图片描述

路线 1:1 -> 2 -> 4,时间为 4+7(隔离)+3=14

路线 2:1 -> 3 -> 4,时间为 5+3(隔离)+5=13

对于 100% 的数据,1 ≤ N ≤ 1000 , 1 ≤ M ≤ 10000, 1 ≤ Ci ≤ 200, 1 ≤ u, v ≤ N, 1 ≤ c ≤ 1000

题解:根据题目可以直接想到最短路,但是比普通最短路多了个限制条件就是选择的城市会有一定的隔离时间,我们可以采用数组存储城市隔离时间,所以我们可以将最短路判断条件改为 if(d[j] > d[p] + w[i] + g[j]) d[j] = d[p] + w[i] + g[j];。题目中路径权都为正整数,不存在负权回路,故可以采用spfa算法求最短路径。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int n,m;
const int N = 3e4 + 100;
int h[N],ne[N],e[N],idx,d[N],g[N],w[N];
bool st[N];

void add(int u,int v,int value)
{
	e[idx] = v,w[idx] = value,ne[idx] = h[u],h[u] = idx ++;
}

void spfa()
{
	memset(d,0x3f,sizeof d);
	queue<int> qu;
	qu.push(1);
	st[1] = true;
	d[1] = 0;
	while(qu.size())
	{
		int p = qu.front();
		qu.pop();
		st[p] = false;
		for(int i = h[p];i != -1;i = ne[i])
		{
			int j = e[i];
			if(d[j] > d[p] + w[i] + g[j])
			{
				d[j] = d[p] + w[i] + g[j];
				if(!st[j]) 
				{
					st[j] = true;
					qu.push(j);
				}
			}
		}
	}
}

int main()
{
	
	memset(h,-1,sizeof h);
	cin >> n >> m;
	for(int i = 1;i <= n;i ++) cin >> g[i];
	
	while(m --)
	{
		int a,b,c;
		cin >> a >> b >> c;
		add(a,b,c);
		add(b,a,c);
	}
	
	spfa();
	if(n == 1) cout << 0 << endl;
	else 
	cout << d[n] - g[n] << endl;
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值