\(\color{#0066ff}{题目描述}\)

1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩。瑞恩被关押在一个迷宫里,迷宫地形复杂,但幸好麦克得到了迷宫的地形图。迷宫的外形是一个长方形,其南北方向被划分为 \(N\) 行,东西方向被划分为 \(M\) 列,于是整个迷宫被划分为 \(N\times M\) 个单元。每一个单元的位置可用一个有序数对(单元的行号,单元的列号)来表示。南北或东西方向相邻的 \(2\) 个单元之间可能互通,也可能有一扇锁着的门,或者是一堵不可逾越的墙。迷宫中有一些单元存放着钥匙,并且所有的门被分成\(P\)类,打开同一类的门的钥匙相同,不同类门的钥匙不同。

大兵瑞恩被关押在迷宫的东南角,即 \((N,M)\) 单元里,并已经昏迷。迷宫只有一个入口,在西北角。也就是说,麦克可以直接进入 \((1,1)\) 单元。另外,麦克从一个单元移动到另一个相邻单元的时间为 \(1\),拿取所在单元的钥匙的时间以及用钥匙开门的时间可忽略不计。

试设计一个算法,帮助麦克以最快的方式到达瑞恩所在单元,营救大兵瑞恩。

\(\color{#0066ff}{输入格式}\)

第 \(1\) 行有 \(3\) 个整数,分别表示 \(N,M,P\) 的值。

第 \(2\) 行是 \(1\) 个整数 \(K\),表示迷宫中门和墙的总数。

第 \(I+2\) 行(\(1\leq I\leq K\)),有 \(5\) 个整数,依次为\(X_{i1},Y_{i1},X_{i2},Y_{i2},G_i\) :

  • 当 \(G_i \geq 1G\) 时,表示 (\(X_{i1},Y_{i1}\)) 单元与 (\(X_{i2},Y_{i2}\)) 单元之间有一扇第 \(G_i\) 类的门
  • 当 \(G_i=0\) 时,表示 (\(X_{i1},Y_{i1}\)) 单元与 (\(X_{i2},Y_{i2}\)) 单元之间有一堵不可逾越的墙(其中,\(|X_{i1}-X_{i2}|+|Y_{i1}-Y_{i2}|=1 ,0\leq G_i\leq P\) )。

第 \(K+3\) 行是一个整数 \(S\),表示迷宫中存放的钥匙总数。

第 \(K+3+J\) 行(\(1\leq J\leq S\)),有 \(3\) 个整数,依次为 \(X_{i1},Y_{i1},Q_i\) :表示第 \(J\) 把钥匙存放在 (\(X_{i1},Y_{i1}\))单元里,并且第 \(J\) 把钥匙是用来开启第 \(Q_i\) 类门的。(其中\(1\leq Q_i\leq P\) )

输入数据中同一行各相邻整数之间用一个空格分隔。

\(\color{#0066ff}{输出格式}\)

将麦克营救到大兵瑞恩的最短时间的值输出。如果问题无解,则输出 -1。

\(\color{#0066ff}{输入样例}\)

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

\(\color{#0066ff}{输出样例}\)

14

\(\color{#0066ff}{数据范围与提示}\)

\(∣X_{i1}−X_{i2}∣+∣Y_{i1}−Y_{i2}∣=1,0\leq G_i \leq P\)

\(1 \leq Q_i\leq P\)

\(N,M,P\leq10, K<150,S\leq 14\)

\(\color{#0066ff}{题解}\)

这是网络流24题????

裸的状压+搜索啊

连记忆化都不用18ms水过

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define _ 0
#define LL long long
inline LL in()
{
LL x=0,f=1; char ch;
while(!isdigit(ch=getchar()))(ch=='-')&&(f=-f);
while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
return x*f;
}
const int inf=0x7fffffff;
int rx[4]={-1,1,0,0};
int ry[4]={0,0,-1,1};
int mp[12][12][2048];
int tp[12][12][4];
int n,m,p,k,s;
std::vector<int> key[12][12];
inline int getdir(int s1,int s2,int t1,int t2)
{
if(t1==s1-1) return 0;
if(t1==s1+1) return 1;
if(t2==s2-1) return 2;
return 3;
}
inline void dfs(int x,int y,int zt)
{
for(int i=0;i<=3;i++)
{
int xx=x+rx[i];
int yy=y+ry[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m)
{
if(tp[x][y][i])
{
if(!(~tp[x][y][i])) continue;
if(!(zt&(1<<(tp[x][y][i]-1)))) continue;
}
int now=zt;
for(int v=0;v<(int)key[xx][yy].size();v++) now|=(1<<(key[xx][yy][v]-1));
if(mp[xx][yy][now]>mp[x][y][zt]+1)
{
mp[xx][yy][now]=mp[x][y][zt]+1;
dfs(xx,yy,now);
}
}
}
}
int main()
{
n=in(),m=in(),p=in(),k=in();
int s1,s2,t1,t2,t,dir;
for(int i=1;i<=k;i++)
{
s1=in(),s2=in(),t1=in(),t2=in(),t=in();
dir=getdir(s1,s2,t1,t2);
t=t? t:-1;
tp[s1][s2][dir]=t;
tp[t1][t2][dir^1]=t;
}
s=in();
for(int i=1;i<=s;i++)
{
s1=in(),s2=in(),t=in();
key[s1][s2].push_back(t);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int v=0;v<(1<<p);v++)
mp[i][j][v]=inf;
int zt=0;
for(int i=0;i<(int)key[1][1].size();i++) zt|=(1<<(key[1][1][i]-1));
mp[1][1][zt]=0;
dfs(1,1,zt);
int min=inf;
for(int i=0;i<(1<<p);i++) min=std::min(min,mp[n][m][i]);
printf(min==inf? "-1":"%d",min);
return 0;
}

P4011 孤岛营救问题的更多相关文章

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

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

  2. 洛谷 P4011 孤岛营救问题【最短路+分层图】

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

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

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

  4. Luogu P4011 孤岛营救问题

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

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

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

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

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

  7. 「LOJ#6121」「网络流 24 题」孤岛营救问题(BFS

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

  8. 孤岛营救问题(BFS+状压DP)

    孤岛营救问题 https://www.luogu.org/problemnew/show/P4011 用状压DP标记拿到钥匙的数量 #include<iostream> #include& ...

  9. loj #6121. 「网络流 24 题」孤岛营救问题

    #6121. 「网络流 24 题」孤岛营救问题   题目描述 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩.瑞恩被关押在一个迷宫里,迷宫地形复杂, ...

随机推荐

  1. Git命令之创建版本

    安装 安装好Git后,将会在桌面生成 这样一个图标 运行后将会是类似控制台程序的黑色窗口,其中mingw64(参考百度百科).这样的话就可以在输入命令 例如 :git 见到下图有详细的用法表示成功否则 ...

  2. 深入理解CPU和异构计算芯片GPU/FPGA/ASIC (下篇)

    3.2.1 CPU计算能力分析 这里CPU计算能力用Intel的Haswell架构进行分析,Haswell架构上计算单元有2个FMA(fused multiply-add),每个FMA可以对256bi ...

  3. JavaScript实现重置表单(reset)的方法

    转自:https://www.jb51.net/article/63305.htm <!DOCTYPE html> <html> <head> <script ...

  4. 【转载】C语言综合实验1—学生信息管理系统

    http://www.cnblogs.com/Anker/archive/2013/05/06/3063436.html 实验题目:学生信息管理系统 实验要求:用户可以选择1-7可以分别进行学生信息的 ...

  5. Cookies和Session的定义与区别

    Cookies和Session二者的定义: 当你在浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择,都纪录下来.当下次你再光临同一个网 ...

  6. 每天一道算法题目(18)——取等长有序数组的上中位数和不等长有序数组的第k小的数

    1.取上中位数 题目: 给定两个有序数组arr1和arr2,两个数组长度都为N,求两个数组中所有数的上中位数.要求:时间复杂度O(logN).      例如:          arr1 = {1, ...

  7. Maven核心概念(转)

    转自 https://www.cnblogs.com/xdp-gacl/p/4051819.html 一.Maven坐标 1.1.什么是坐标? 在平面几何中坐标(x,y)可以标识平面中唯一的一点. 1 ...

  8. ROS探索总结(二)——ROS总体框架

    个人分类: ROS 所属专栏: ROS探索总结   一.  总体结构        根据ROS系统代码的维护者和分布来标示,主要有两大部分:      (1)main:核心部分,主要由Willow G ...

  9. C++指针作为函数的参数进行传递时注意的问题

    应注意问题: 当指针作为函数的参数进行传递的时候,本质上还是进行的"值传递",也就是复制了一个新的指向该地址的指针变量. 只有在被调函数中,对指针进行引用操作,才可以达到不需要返回 ...

  10. Tensorflow梯度下降应用

    import tensorflow as tfimport numpy as np #使用numpy生成随机点x_data = np.random.rand(100)y_data = x_data*0 ...