洛谷 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#Image.FromFile图形加载异常处理
public void UpdateImg(string picpath) { //更新至控件中 PnlImageShow.BackgroundImage = LoadImgPath(picpath) ...
- [日常] 研究redis未授权访问漏洞利用过程
前提:redis允许远程连接,不需要密码 1522057495.583846 [0 123.206.24.121:50084] "set" "dUHkp" &q ...
- Java Swing实战(一)JFrame和JTabbedPane容器
概述: 项目是一个桌面程序,涉及标签和按钮组件.布局管理器组件.面板组件.列表框和下拉框组件等组件,以及Swing事件处理机制. 下面先从最基础的界面开始. /** * @author: lishua ...
- HDU2181(KB2-C)
哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HTML5扩展之微数据与丰富网页摘要——张鑫旭
一.微数据是? 一个页面的内容,例如人物.事件或评论不仅要给用户看,还要让机器可识别.而目前机器智能程度有限,要让其知会特定内容含义,我们需要使用规定的标签.属性名以及特定用法等.举个简单例子,我们使 ...
- visibilitychange:API详解
利用页面可见性API搞个怪 继各大站点.博客在用console发招聘.玩游戏.埋彩蛋之后(知乎相关链接),小剧似乎又发现了一个好玩儿的东西,目测会火,利用页面可见性API做些小技俩. 页面可见性是什么 ...
- JavaScript之Array
JavaScript是一门非常灵活的动态语言,涵盖的内容也挺多,<JavaScript高级程序设计>看了也有两遍,但是在实际开发的时候,还是有很多东西记不清,然后还得去翻书,特别是一些Ar ...
- 用Struts2实现列表显示和分页功能
引用自http://www.2cto.com/kf/201309/243730.html BlogDAO.java文件 /** 根据条件(默认一张表所有数据)返回多条记录 */ public List ...
- APP之红点提醒三个阶段
下面这个页面就是我们进入APP后的主界面.客户选项的红点上数字就是显示我们没有查看的客户总数量. 当我们切换到客户这个fragment时,会显示贷款客户数量与保险客户数量. 当我们随便点击入一 ...
- centos7 yum安装mysql | mariaDb
mysql解释: mysql数据库是最常用的一种数据库,下面我来在centos7的迷你版上安装一下mysql.绝对纯净的环境哦 centos: CentOS-7-x86_64-Minimal-1 ...