洛谷 P4011 孤岛营救问题【最短路+分层图】
题外话:昨夜脑子昏沉,今早一调试就过了...错误有:我忘记还有墙直接穿墙过...memset初始化INF用错了数...然后手残敲错一个状态一直过不了样例...要是这状态去比赛我简直完了......orz
题目链接:https://www.luogu.org/problemnew/show/P4011
输入输出样例
4 4 9
9
1 2 1 3 2
1 2 2 2 0
2 1 2 2 0
2 1 3 1 0
2 3 3 3 0
2 4 3 4 1
3 2 3 3 0
3 3 4 3 0
4 3 4 4 0
2
2 1 2
4 2 1
14
题解:分层图最短路问题。最多就10类门,一看就是状态压缩最大空间 (1<<11)-1 ,很友好...d[i][sta]表示到点i,状态为sta的最短路长度(sta就是到i点前所持有的钥匙的状态)。
代码:
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
#define CLR(a, b) memset((a), (b), sizeof((a)))
using namespace std;
const int N = ;
const int states = <<;
const int INF = 0x3f3f3f3f; int d[N][states], vis[N][states];
int id[N][N];
int key[N]; //key[i]:i点有哪些钥匙(状态)
int mp[N][N]; //mp[i][j]:i到j有哪类门
int dx[] = {, , -, };
int dy[] = {, , , -};
int n, m, p;
struct qnode{
int v;
int x;//状态
qnode(int _v=,int _x=):v(_v),x(_x){}
};
bool SPFA(int st, int ed) {
CLR(vis, );
CLR(d, INF);
d[st][] = ;
queue<qnode> q;
while(!q.empty()) q.pop();
q.push(qnode(st, ));
while(!q.empty()) {
qnode t = q.front(); q.pop();
int u = t.v;
int sta = t.x;
vis[u][sta] = false; if(key[u]) sta |= key[u];
for(int i = ; i < ; i++) {
int x = (u+m-)/m + dx[i];
int y = (u%m?u%m:m) + dy[i]; if(x < || x > n || y < || y > m) continue;
int v = id[x][y];
//不是墙 并且 有对应钥匙 或者没有门。
if(mp[u][v]!= && ( (sta&(<<mp[u][v])) || mp[u][v]==-)) {
if(d[v][sta] > d[u][t.x] + ) {
d[v][sta] = d[u][t.x] + ;
if(!vis[v][sta]) {
vis[v][sta] = true;
q.push(qnode(v, sta));
}
}
}
}
}
int ans = INF;
for(int i = ; i < states; ++i) ans = min(ans, d[ed][i]);
if(ans == INF) puts("-1");
else printf("%d\n", ans);
}
int main() {
int i, j, k, x1, y1, x2, y2, q, sum;
scanf("%d%d%d", &n, &m, &p);//行,列,门和墙的总数 int cnt = ;
for(i = ; i <= n; ++i)
for(j = ; j <= m; ++j) id[i][j] = ++cnt; CLR(mp, -);
scanf("%d", &k);//门和墙总数
for(i = ; i <= k; ++i) {
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &q);
int id1 = id[x1][y1];
int id2 = id[x2][y2];
mp[id1][id2] = mp[id2][id1] = q;
}
scanf("%d", &sum);//钥匙总数
for(i = ; i <= sum; ++i) {
scanf("%d%d%d", &x1, &y1, &q);
key[id[x1][y1]] |= (<<q);
}
SPFA(, n*m);
return ;
}
洛谷 P4011 孤岛营救问题【最短路+分层图】的更多相关文章
- 洛谷 [P4011] 孤岛营救问题
状压+BFS 通过观察数据范围可知,我们应该状压钥匙种类,直接BFS即可 注意,一个点处可能不知有一把钥匙 #include <iostream> #include <cstdio& ...
- 洛谷P4011 孤岛营救问题(状压+BFS)
传送门 和网络流有半毛钱关系么…… 可以发现$n,m,p$都特别小,那么考虑状压,每一个状态表示位置以及钥匙的拥有情况,然后每次因为只能走一步,所以可以用bfs求出最优解 然后是某大佬说的注意点:每个 ...
- 洛谷 P4011 孤岛营救问题【bfs】
注意: 一个点可能有多把钥匙,所以把每个点有钥匙的情况状压一下 两个点之间有障碍的情况只给出了单向,存的时候记得存一下反向 b[i][j]表示当前点拥有钥匙的状态,g[x1][y1][x2][y2]表 ...
- Luogu P4011 孤岛营救问题(状态压缩+最短路)
P4011 孤岛营救问题 题意 题目描述 \(1944\)年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到 ...
- 洛谷P4011 【网络流24题】 孤岛营救问题 (BFS+状压)
一道妙题啊......(不知道为什么这道题的标签是网络流,不需要用网络流啊) 如果没有门和钥匙,连边(边权为1)求最短路就行了. 但是有这两个因素的限制,我们采用分层建图的思想,一共2p层,每层对应持 ...
- Luogu P4011 孤岛营救问题
题目链接 \(Click\) \(Here\) 注意坑点:一个地方可以有多把钥匙. 被卡了一会,调出来发现忘了取出来实际的数字,直接把二进制位或上去了\(TwT\),其他的就是套路的分层图最短路.不算 ...
- 洛谷P4009 汽车加油行驶问题(分层最短路)
传送门 说好的网络流24题呢……上次是状压dp,这次怎么又最短路了…… 不过倒是用这题好好学了一下分层图最短路 把每一个位置$(x,y)$,油量剩余$k$表示为一个状态,然后转化成一个$n$进制数,这 ...
- BZOJ:2763-[JLOI2011]飞行路线(最短路分层图)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 解题心得: 第一次见到分层最短路.其实题中说选择k条路径免费,那怎么选k条路径并没 ...
- P4011 孤岛营救问题
\(\color{#0066ff}{题目描述}\) 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克 ...
随机推荐
- C#关于操作符重载与转换
随便写写 首先,假设我们有一个Person类型 其类型定义如下 class Person { public string Name { get; set; } = "Person" ...
- 工程中添加工程依赖 Xcode iOS
有时我们需要在一个主工程中添加其他的子工程,用来对子工程进行编写修改或者是利用子工程中的库文件等等操作,这时候我们需要用到工程的嵌套. 步骤:(看图说话) 1.新建主工程,名为TestTTTT ...
- 使用IDEA工具配置和运行vue项目(详细其中的坑)
刚来公司实习发现公司的前端使用的是vue,之前根本就没有听说过.然后一上来就需要看代码,but but 就是没有文档什么的东西, 就需要自己去研读,我就想去运行其中的前端和后端联调起来方便理解,结果在 ...
- 基于JSP的RSS阅读器的设计与实现
阅读器访问地址:http://easyrss.tk/,欢迎体验! 阅读导览 一. 概述 二. 设计的基本概念和原理 三. 设计方案 四. 主要源代码 五. 阅读器使用说 ...
- PHPCMS V9 fsockopen 函数被禁用解决方案
PHPCMS V9 fsockopen 禁用解决方案, 把fsockopen 替换成 pfsockopen 替换文件:phpsso_server/api/uc_client_1_5/client.ph ...
- CentOS7系列--5.2CentOS7中配置和管理Docker
CentOS7配置和管理Docker Docker是操作系统级别的虚拟化工具,它能自动化布署在容器中的应用 1. 安装Docker 1.1. 安装Docker相关软件 [root@server1 ~] ...
- python学习笔记之——python模块
1.python模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python ...
- Android的onCreateOptionsMenu()创建菜单Menu
android一共有三种形式的菜单: 1.选项菜单(optinosMenu) 2.上下文菜单(ContextMenu) 3.子菜 ...
- 搭建Kafka开发环境
Kafka版本是:kafka_2.10-0.8.2.1 1.maven工程方式 在pom.xml中配置kafka依赖 1 2 3 4 5 <dependency> <grou ...
- 神奇的负Margin
在做slide时候一般都是采用父元素超宽+overflow的做法,今天发现了用margin-right:-100%;可以让子元素全部重叠起来.效果也是不错的