当前位置: 首页 > news >正文

分层图 的尝试学习 1.0

分层图:
分层图的最短路:
又叫做 扩点最短路。不把实际位置看做是图上的点,而是把实际位置及其状态的组合,(一个点有若干的状态,所以一个点会扩充出来若干点)看做是图上的点,然后搜索bfs或者dijkstra的过程不变。只是扩了点(分层)而已。
原理很简单,核心在于如何扩点,如何到达,如何算距离,每个题可能都不一样。注意计算扩充之后的点数。
添加链接描述
题意:
二维网格,只包含空房间,障碍,起点,钥匙和对应的锁(只有拿到对应的钥匙才能开对应的锁,否则锁的位置和障碍没什么区别,无法通过)问获得所有钥匙所需要移动的最小次数(相当于最短路),可以上下左右移动如果无法;获得所有的钥匙,返回-1

边长最多是30,钥匙最多是6
可以用一个数来代表这个点所获得的钥匙的状态。扩充后一共有30302^6 个点。57600个点。我感觉这道题的分层的感觉不是很强烈吧,感觉更多的是状态压缩。
使用三元组 (x,y,mask)表示当前状态。其中(x,y)代表当前所处的位置,mask 是一个二进制数,长度恰好等于网格中钥匙的数量,mask的第I个二进制位为1,当且仅当,我们已经获得了网格中的第i把钥匙。
之后使用广度优先搜索。

添加链接描述
题意:
对于一个有权无向图,可以将最多k条边 化为0,问从起点到终点的最短路。
分层图,可以看成有k+1 层图,代表了 使用0次,1次…k次 的图。
图和图之间 通过权值为0的边连接。
进行扩点,最多1e5个点。
使用二维的dis ,和vis 数组来标记状态。(其中一维代表了使用了几次的免费)

dij求 最短路 的时候,越晚确定 到原点最短路 的点,点 到原点的 距离越远。也就是说 根据 节点 确定dis 的顺序,dis 的数值 是不减 的。(毕竟后面的点 是前面点 松弛过来的,然后边权非负)
所以,扩点求最短路。最先遇到这个点 某个状态时,这个dis 是这个点所有状态里面的最短。
所以 在 dij ,如果遇到了终点,那么不管他的使用过的免费次数是多少,直接返回。

#include <bits/stdc++.h>
using namespace std;
#define int long long 
const int N = 1e4 + 10;
const int M = 5e5 + 10;
int h[M], to[M], ne[M];
int w[M];int tot = 1;
struct node
{int x;int k;// 使用了多少次的 免费机会int y;// 距离bool operator<(const node &a) const{return a.y < y;}
};
void add(int u, int v, int ww)
{to[tot] = v;ne[tot] = h[u];w[tot] = ww;h[u] = tot++;
}void solve()
{int n, m, k;cin >> n >> m >> k;vector<vector<int>> dis(n, vector<int>(k + 1, 1e9));vector<vector<int>> vis(n, vector<int>(k + 1, 0));int s, e;cin >> s >> e;int u, v, ww;while (m--){cin >> u >> v >> ww;add(u, v, ww);add(v, u, ww);}auto dij = [&](int s) -> void{dis[s][0] = 0;priority_queue<node> q;q.push({s,0,0});// 代表 点,使用免费的次数 ,距离while (!q.empty()){auto tt=q.top();int u=tt.x;int j=tt.k; int cost=tt.y;q.pop();if (vis[u][j])continue;vis[u][j] = 1;if (u==e){cout<<cost<<"\n";return; }for (int i = h[u]; i; i = ne[i]){int v = to[i];// 使用 免费 的机会if (j+1<=k&&dis[v][j+1]>dis[u][j]){dis[v][j+1]=dis[u][j];q.push({v,j+1,dis[v][j+1]});}// 不使用 免费 的机会 if (dis[v][j]>dis[u][j]+w[i]){dis[v][j]=dis[u][j]+w[i];q.push({v,j,dis[v][j]});}}}};dij(s);}

相关文章:

  • 【C++】C++的Vector使用和实现
  • 软件架构设计师教程 第11章 11.4 边缘计算概述 笔记
  • neo4j小白入门
  • 询盘鸭独立站
  • OpenCV图像文件读写(4)解码图像数据函数imdecode()的使用
  • Rustrover2024.2 正式发布:个人非商用免费,泰裤辣
  • idea 创建多模块项目
  • 极狐GitLab 17.4 重点功能解读【三】
  • 第三章 Docker中常用软件安装部署练习
  • win自带录屏怎么用?让视频制作更简单!
  • Spring Cloud全解析:服务调用之多个FeignClient调用服务名称相同
  • 在Pycharm中安装Cv2
  • Page<T>类型数据间的复制
  • Spring-bean实例化的方式
  • LeetCode 每日一题 2024/9/23-2024/9/29
  • [LeetCode] Wiggle Sort
  • 「面试题」如何实现一个圣杯布局?
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【Linux系统编程】快速查找errno错误码信息
  • 10个最佳ES6特性 ES7与ES8的特性
  • golang 发送GET和POST示例
  • js继承的实现方法
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Spring-boot 启动时碰到的错误
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 基于Android乐音识别(2)
  • 坑!为什么View.startAnimation不起作用?
  • 深度学习中的信息论知识详解
  • 延迟脚本的方式
  • 说说我为什么看好Spring Cloud Alibaba
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (十八)三元表达式和列表解析
  • (一)VirtualBox安装增强功能
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)shell调试方法
  • (转)可以带来幸福的一本书
  • (轉貼) UML中文FAQ (OO) (UML)
  • ***测试-HTTP方法
  • .ai域名是什么后缀?
  • .cfg\.dat\.mak(持续补充)
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .Net 知识杂记
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET编程——利用C#调用海康机器人工业相机SDK实现回调取图与软触发取图【含免费源码】
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • :中兴通讯为何成功
  • []FET-430SIM508 研究日志 11.3.31