题外话:昨夜脑子昏沉,今早一调试就过了...错误有:我忘记还有墙直接穿墙过...memset初始化INF用错了数...然后手残敲错一个状态一直过不了样例...要是这状态去比赛我简直完了......orz

题目链接:https://www.luogu.org/problemnew/show/P4011

输入输出样例

输入样例#1:

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
输出样例#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 孤岛营救问题【最短路+分层图】的更多相关文章

  1. 洛谷 [P4011] 孤岛营救问题

    状压+BFS 通过观察数据范围可知,我们应该状压钥匙种类,直接BFS即可 注意,一个点处可能不知有一把钥匙 #include <iostream> #include <cstdio& ...

  2. 洛谷P4011 孤岛营救问题(状压+BFS)

    传送门 和网络流有半毛钱关系么…… 可以发现$n,m,p$都特别小,那么考虑状压,每一个状态表示位置以及钥匙的拥有情况,然后每次因为只能走一步,所以可以用bfs求出最优解 然后是某大佬说的注意点:每个 ...

  3. 洛谷 P4011 孤岛营救问题【bfs】

    注意: 一个点可能有多把钥匙,所以把每个点有钥匙的情况状压一下 两个点之间有障碍的情况只给出了单向,存的时候记得存一下反向 b[i][j]表示当前点拥有钥匙的状态,g[x1][y1][x2][y2]表 ...

  4. Luogu P4011 孤岛营救问题(状态压缩+最短路)

    P4011 孤岛营救问题 题意 题目描述 \(1944\)年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到 ...

  5. 洛谷P4011 【网络流24题】 孤岛营救问题 (BFS+状压)

    一道妙题啊......(不知道为什么这道题的标签是网络流,不需要用网络流啊) 如果没有门和钥匙,连边(边权为1)求最短路就行了. 但是有这两个因素的限制,我们采用分层建图的思想,一共2p层,每层对应持 ...

  6. Luogu P4011 孤岛营救问题

    题目链接 \(Click\) \(Here\) 注意坑点:一个地方可以有多把钥匙. 被卡了一会,调出来发现忘了取出来实际的数字,直接把二进制位或上去了\(TwT\),其他的就是套路的分层图最短路.不算 ...

  7. 洛谷P4009 汽车加油行驶问题(分层最短路)

    传送门 说好的网络流24题呢……上次是状压dp,这次怎么又最短路了…… 不过倒是用这题好好学了一下分层图最短路 把每一个位置$(x,y)$,油量剩余$k$表示为一个状态,然后转化成一个$n$进制数,这 ...

  8. BZOJ:2763-[JLOI2011]飞行路线(最短路分层图)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 解题心得: 第一次见到分层最短路.其实题中说选择k条路径免费,那怎么选k条路径并没 ...

  9. P4011 孤岛营救问题

    \(\color{#0066ff}{题目描述}\) 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克 ...

随机推荐

  1. C#比较两个字符串的相似度【转】

    原文地址:http://www.2cto.com/kf/201202/121170.html 我们在做数据系统的时候,经常会用到模糊搜索,但是,数据库提供的模糊搜索并不具备按照相关度进行排序的功能. ...

  2. StreamRead和StreamWriter的使用

    //StreamRead来读取一个文件 using (StreamReader sr = new StreamReader(@"C:\Users\enle\Desktop\新建文本文档.tx ...

  3. 什么是memcached?

    缓存是一种常驻与内存的内存数据库,内存的读取速度远远快于程序在磁盘读取数据的速度.我们在设计程序的时候常常会考虑使用缓存,将经常访问的数据放到内存上面这样可以提高访问数据的速度,同时可以降低磁盘或数据 ...

  4. [Redis] redis数据备份恢复与持久化

    数据库备份,使用save命令,将会在redis的安装目录中生成dump.rdb 例如:在我的目录下 redis/src/dump.rdb 使用命令config get dir,获取当前redis的安装 ...

  5. vue+element ui 的表格列使用组件

    前言:工作中用到 vue+element ui 的前端框架,有这个场景:很多表格的列有许多一样的,所以考虑将列封装为组件.转载请注明出处:https://www.cnblogs.com/yuxiaol ...

  6. node.js(http协议)

    七层网络协议 应用层:浏览器(http,FTP,DNS,SMTP,TeInet)(邓哥)表示层:加密,格式转换(怕别人偷看,加密摩斯电码)会话层:解除或者建立和其他节点的联系(邓哥在想追这个女孩,不再 ...

  7. fuzz实战之honggfuzz

    Honggfuzz实战 前言 本文介绍 libfuzzer 和 afl 联合增强版 honggfuzz .同时介绍利用 honggfuzz 来 fuzz 网络应用服务. 介绍 honggfuzz 也是 ...

  8. Vue 框架-12-Vue 项目的详细开发流程

    Vue 框架-12-Vue 项目的详细开发流程 首先,如果你还不了解 Vue 脚手架怎么搭建? 默认的环境中有哪些文件? 文件大概是什么作用? 那么,您要先查看之前的文章才有助于你理解本篇文章: Vu ...

  9. CSS 小结笔记之背景

    背景相关属性主要有: background-color  背景颜色 background-image 背景图片 background-repeat 是否平铺 repeat (默认平铺) | repea ...

  10. C语言高精度乘法

    #include <stdio.h> void highPrecision (int N ); ] = {, }, length = ; //开辟一个大的数组,全局变量length记录长度 ...