BD202301 公园
今天是六一节,小度去公园玩,公园一共 NN 个景点,正巧看到朋友圈度度熊也在这个公园玩,于是他们约定好一块去景点 NN。 小度当前所在景点编号为 TT,从一个景点到附近的景点需要消耗的体力是 TETE,而度度熊所在景点编号为 FF ,移动消耗为 FEFE。 好朋友在一块,赶路都会开心很多,所以如果小度和度度熊一块移动(即在相同位置向相同方向移动),每一步他俩的总消耗将会减少 SS。 求他俩到景点 NN 时,所需要的总消耗最少是多少?
格式
输入格式:
第一行三个数值,TE,FE,STE,FE,S ,分别代表小度移动消耗值,度度熊移动消耗值,一起移动的消耗减少值。1 \le TE,FE,S \le 40000, S \le TE+FE1≤TE,FE,S≤40000,S≤TE+FE; 第二行四个数值,T,F,N,MT,F,N,M ,分别代表小度出发点,度度熊出发点,目标节点,总路径数。1 \le T,F,N,M \le 400001≤T,F,N,M≤40000; 接下来 MM 行,每行两个整数 X,YX,Y,代表连通的两个景点。1 \le X,Y \le N1≤X,Y≤N。
输出格式:
一个整数,即总消耗最小值。如果不能到达 NN , 输出-1。
样例 1
输入:
4 4 3
1 2 8 8
1 4
2 3
3 4
4 7
2 5
5 6
6 8
7 8
复制
输出:
22
复制
1.
图信息,邻接表存储图信息,vector<vectaor<int>>g变量存储图的信息.
外层的vector数组下标表示每一个点,下标映射变量vector<int>表示从这个点出发可以通往哪些点.
2.
一共有N个景点,选择开辟N+1空间的大小,这样下标直接表示景点不需要偏移量.
3.
小度在T点,熊在F点,他们都要去N点,可以理解他们首先会在一个景点相遇,然后前往N点,极端的情况就是他们在N景点相遇.
因此需要存储三个信息,T点出发到达所有点花费的体力,F点距出发到达所有点花费的体力,N点出发到达其他所有点花费的体力.
bfs填写这三个表即可.
#include<bits/stdc++.h>
using namespace std;
#define int long long // 将 int 定义为 long long 类型,便于处理大数
#define endl '\n' // 将 endl 定义为换行符
using p=pair<int,int>; // 定义一个名为 p 的类型,表示一对整数
vector<p> d={
{0,1},{1,0},{0,-1},{-1,0}}; // 定义一个表示四个方向的向量数组
/*
N 个景点,去景点 N. 1~N 个点.
小度在 T 点,走一步消耗体力 TE
熊在 F 点,走一步消耗体力 FE
如果一起走,总消耗减少 S
求最少的消耗.
*/
int TE, FE, S, T, F, N, M; // 定义输入的变量
vector<vector<int>> g; // 邻接表存储图的信息
vector<int> dis_xiaodu; // 小度到达各点的体力消耗
vector<int> dis_xiong; // 熊到达各点的体力消耗
vector<int> dis_n; // 从目标点出发到达各点的体力消耗
int ret=LLONG_MAX; // 初始化最小消耗为最大值
// BFS 填写体力消耗表
void bfs(vector<int>& dis, int start, int nums) {
dis[start] = 0; // 起点的消耗为 0
queue<int> q; // 定义队列进行 BFS
q.push(start); // 起点入队
while (!q.empty()) { // 队列不为空时进行 BFS
auto top = q.front(); // 获取队首元素
q.pop(); // 队首元素出队
for (auto& x : g[top]) { // 遍历与队首元素相连的所有点
if (dis[x] == -1) { // 如果该点未被访问
dis[x] = dis[top] + nums; // 更新到该点的消耗
q.push(x); // 将该点入队
}
}
}
}
// 解决问题的主函数
void solve()