扩点最短路

news/2024/9/20 10:41:26

扩点最短路

不把实际位置看作图上的点,而是把实际位置和该位置的所有状态的组合看作是图上的点,BFS 或者 Dijkstra 的过程不变,只是增加了一些点。

864. 获取所有钥匙的最短路径

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>using namespace std;class Solution {
public:int rows, columns;// 最多 6 把钥匙int max_k = 6;int key = 0;vector<int> move{-1, 0, 1, 0, -1};bool isCoordinateLegal(int row, int column) {return row >= 0 && row < rows && column >= 0 && column < columns;}// BFSint shortestPathAllKeys(vector<string> &grid) {rows = grid.size();columns = grid[0].size();// (x, y, 持有钥匙的状态)queue<vector<int>> q;// 找起点for (int i = 0; i < rows; ++i) {for (int j = 0; j < columns; ++j) {if (grid[i][j] == '@') {q.emplace(vector<int>{i, j, 0});} else if (grid[i][j] >= 'a' && grid[i][j] <= 'f') {// 计算获得所有钥匙的最终状态key |= (1 << (grid[i][j] - 'a'));}}}// 表示当前位置的某个状态是否从队列中弹出过,状态是指持有钥匙的情况vector<vector<vector<bool>>> visited(rows, vector<vector<bool>>(columns));for (int i = 0; i < rows; ++i)for (int j = 0; j < columns; ++j)visited[i][j].resize(key, false);int step = 1;while (!q.empty()) {int size = q.size();// 逐层弹出for (int i = 0; i < size; ++i) {auto f = q.front();q.pop();int x = f[0];int y = f[1];// 经过(x, y)后,到达下个点前持有钥匙的状态int s = f[2];// 四周for (int j = 0; j < 4; ++j) {int nx = x + move[j];int ny = y + move[j + 1];// 越界if (!isCoordinateLegal(nx, ny)) continue;char ch = grid[nx][ny];// 墙if (ch == '#') continue;// 锁,且没对应钥匙if (ch >= 'A' && ch <= 'F' && (s & (1 << (ch - 'A'))) == 0) continue;// 钥匙,更新持有的钥匙状态int ns = s;if (ch >= 'a' && ch <= 'f')ns |= (1 << (ch - 'a'));// 获得所有钥匙了if (ns == key) return step;if (visited[nx][ny][ns]) continue;visited[nx][ny][ns] = true;q.emplace(vector<int>{nx, ny, ns});}}step++;}return -1;}
};

LCP 35. 电动车游城市

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>using namespace std;class Solution {
public:struct cmp {bool operator()(vector<int> &v1, vector<int> &v2) {return v1[2] > v2[2];}};int electricCarPlan(vector<vector<int>> &paths, int cnt, int start, int end, vector<int> &charge) {int n = charge.size();vector<vector<pair<int, int>>> graph(n);// 无向图for (const auto &item: paths) {graph[item[0]].emplace_back(make_pair(item[1], item[2]));graph[item[1]].emplace_back(make_pair(item[0], item[2]));}// (点, 到这个点的剩余电量, 代价)priority_queue<vector<int>, vector<vector<int>>, cmp> heap;// vector[i][j] 为到达 i 点时剩余 j 电量的最小代价vector<vector<int>> distance(n, vector<int>(cnt + 1, INT_MAX));// 访问标记vector<vector<bool>> visited(n, vector<bool>(cnt + 1, false));heap.emplace(vector<int>{start, 0, 0});distance[start][0] = 0;while (!heap.empty()) {auto top = heap.top();heap.pop();int position = top[0];int power = top[1];int cost = top[2];// 结束if (position == end) return cost;if (visited[position][power]) continue;visited[position][power] = true;// 充一格电,到图中扩出来的点,也就是这个点的其他状态if (power < cnt&& !visited[position][power + 1]&& (cost + charge[position] < distance[position][power + 1])) {distance[position][power + 1] = cost + charge[position];heap.emplace(vector<int>{position, power + 1, distance[position][power + 1]});}// 不充电,直接去别的点for (const auto &item: graph[position]) {int nextPosition = item.first;int restPower = power - item.second;int nextCost = cost + item.second;// 到不了下个点,或者下个状态已经弹出过,就跳过if (restPower < 0 || visited[nextPosition][restPower]) continue;if (nextCost < distance[nextPosition][restPower]) {distance[nextPosition][restPower] = nextCost;heap.emplace(vector<int>{nextPosition, restPower, nextCost});}}}return -1;}
};

P4568 [JLOI2011] 飞行路线

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>using namespace std;int n, m, k, s, t;vector<int> head;
vector<int> nxt;
vector<int> to;
vector<int> weight;
int cnt;void build() {head.resize(n, 0);fill(head.begin(), head.end(), 0);nxt.resize((m << 1) + 1);to.resize((m << 1) + 1);weight.resize((m << 1) + 1);cnt = 1;
}void addEdge(int u, int v, int w) {nxt[cnt] = head[u];to[cnt] = v;weight[cnt] = w;head[u] = cnt;cnt++;
}struct cmp {bool operator()(vector<int> &v1, vector<int> &v2) {return v1[2] > v2[2];}
};int main() {cin >> n >> m >> k >> s >> t;build();for (int i = 0, u, v, w; i < m; ++i) {cin >> u >> v >> w;addEdge(u, v, w);addEdge(v, u, w);}// distance[i][j] 为到达 i 点,剩余免费乘坐次数 j 次的最少代价vector<vector<int>> distance(n, vector<int>(k + 1, 0x7fffffff));// 访问标记vector<vector<bool>> visited(n, vector<bool>(k + 1, false));// (点,到点后剩余的免费次数,最少代价)priority_queue<vector<int>, vector<vector<int>>, cmp> heap;distance[s][k] = 0;heap.emplace(vector<int>{s, k, 0});while (!heap.empty()) {auto top = heap.top();heap.pop();int u = top[0];int free = top[1];int cost = top[2];// 结束if (u == t) {cout << cost;return 0;}if (visited[u][free]) continue;visited[u][free] = true;for (int ei = head[u]; ei > 0; ei = nxt[ei]) {int v = to[ei];int w = weight[ei];// 使用一张票if (free > 0&& !visited[v][free - 1]&& cost < distance[v][free - 1]) {distance[v][free - 1] = cost;heap.emplace(vector<int>{v, free - 1, cost});}// 不使用if (!visited[v][free]&& cost + w < distance[v][free]) {distance[v][free] = cost + w;heap.emplace(vector<int>{v, free, cost + w});}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/62447.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

设计原理图:417-基于XCVU9P+ C6678的8T8R的无线MIMO平台

基于XCVU9P+ C6678的8T8R的无线MIMO平台 一、板卡概述 北京太速科技板卡基于TI TMS320C6678 DSP和XCVU9P高性能FPGA,FPGA接入4片AD9361 无线射频,构建8输入8输出的无线MIMO平台,丰富的FPGA资源和8核DSP为算法验证和信号处理提供强大能力。二、技术指标 ● 板卡为自定义结构…

“模”力十足!天翼云息壤一体化智算服务平台训推服务能力重磅升级!

9月4日,“天翼云息壤——大模型训推一体化服务能力升级”线上发布会成功举办。会上,息壤平台训推服务能力重磅升级,新增闭源、多模态基座大模型以及数据集,支持万卡规模训练,训练稳定性再次提升,新增体验空间,为基础大模型训练、行业大模型训推提供一站式解决方案。9月4…

全国省市县区的JOSN

[{"name": "北京市","code": "110000","city": [{"name": "市辖区","code": "110100","area": [{"name": "东城区","code": "11010…

关于api接口详解大全

API接口,即应用程序编程接口(Application Programming Interface),是一组预定义的函数或协议,它允许不同的软件应用程序之间进行交互。API在现代软件开发中扮演着至关重要的角色,它促进了不同系统之间的集成和通信,为开发者提供了强大的工具来构建更加高效、安全和创新的…

Amazon Bedrock 模型微调实践(二):数据准备篇

本博客内容翻译自作者于 2024 年 9 月在亚马逊云科技开发者社区发表的同名博客: “Mastering Amazon Bedrock Custom Models Fine-tuning (Part 2): Data Preparation for Fine-tuning”亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技…

Spark(一)概述

基本概念Spark是一种基于内存的快速、通用、可扩展的大数据分析计算引擎Spark vs HadoopSpark和Hadoop的根本差异是多个作业之间的数据通信问题:Spark多个作业之间数据通信是基于内存,而Hadoop是基于磁盘Hadoop Spark类型 分布式基础平台, 包含计算, 存储, 调度 分布式计算工…

基于语义增强的少样本检测,突破新类别偏见 | ICIP24

Few-shot目标检测(FSOD)旨在在有限标注实例的情况下检测新颖对象,在近年取得了显著进展。然而,现有方法仍然存在偏见表示问题,特别是在极低标注情况下的新颖类别。在微调过程中,一种新颖类别可能会利用来自相似基础类别的知识来构建自己的特征分布,导致分类混淆和性能下…

如何解决Warning: include(): Failed opening file_path for inclusion问题

解决方法检查文件路径确认文件路径是否正确无误,包括路径中的每个目录和文件名。验证文件是否存在使用file_exists()函数检查文件是否真的存在于指定路径上。检查文件权限确认文件具有足够的权限供当前用户读取。可以使用chmod命令修改文件权限:bashchmod 644 file_path确认文…