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

题意:

(原题太长我就不贴了,简单叙述一下)
一个N*M的迷宫,每个单元格之间可能有门或者墙,也可能啥也没有。门和墙的总数为K(会读入墙和门的位置坐标)
门存在种类,只有拥有对应种类的钥匙才可以打开这类门
钥匙的总量为S(会读入钥匙的坐标)
从一个单元格到另一个单元格时间为1
现在从左上角(1,1)出发,到右下角(N,M),最少花费多少时间?
针对样例,看图分析

紫色为钥匙
橙色为墙或者门的种类
绿色为线路

题解:

这就是网络流吗?爱了爱了
迷宫的题一般用BFS就可以做
有了钥匙我们就状压+BFS
状态压缩钥匙,是为了方便记录每一把钥匙的状态
就比如当前状态是“100”,说明我有第三把钥匙,因为第三位(从右往左)是1,而“100”对应的是4,你会发现你拥有第i把钥匙,状态就是2i-1(十进制下),这样我们就可以用二进制来存储钥匙信息
key|=Key [ x ] [ y ] //就是将当前已有钥匙的状态给key
我们在开门时验证自己有钥匙的方式:
( mp [x] [y] [u.x] [u.y] & key ) ! = mp [x] [y] [u.x] [u.y]
[x][y]表示当前单元格,[u.x][u.y]表示上一个单元格
mp就表示两个单元格之间门的编号,也可能是墙(表示方式和钥匙一样),直接与钥匙&运算,如果运算后还是本身,说明有指定的钥匙(因为有钥匙说明那一位为1,1&1=1,还是本身,如果没有指定钥匙,说明那一位是0,0&1=0,值就发生改变)

然后就是bfs的走迷宫过程,走迷宫有四种状态要continue
1.如果超格子了
2.如果撞墙了
3.如果遇到门但是木有钥匙
4.之前走过了

坑点:
1.钥匙可以重复使用而非用过即毁
2.一个地方可以存放多个钥匙,所以保存钥匙时不要将前一个覆盖掉
3.初始点也可以放钥匙
4.存在走不通的情况记得输出-1

代码:

代码中注释非常详细

#include<bits/stdc++.h>
using namespace std;
const int dx[]={1,-1,0,0};//增量数组
const int dy[]={0,0,1,-1};
int vis[25][25][40005],x,y,xx,yy,p,pw[105],mp[16][16][16][16],Key[20][20],n,m,tot;
struct nod{int x,y,key,stp;}q[5000005];//q为广搜用的队列
int bfs(){int h=1,t=1;vis[1][1][Key[1][1]]=1;//一开始就有位于(1,1)的钥匙q[t]=(nod){1,1,Key[1][1],0};for(;h<=t;++h){nod u=q[h];//取队头for(int k=0;k<4;++k){int x=u.x+dx[k];int y=u.y+dy[k];int key=u.key;//已有钥匙 int stp=u.stp;//已走步数 if(x<1||y<1||x>n||y>m)continue;//如果超出格子则跳过if(mp[x][y][u.x][u.y]==-1)continue;//如果两个格子之间有墙则跳过if((mp[x][y][u.x][u.y]&key)!=mp[x][y][u.x][u.y])continue;//如果两个格子之间有门而且手上所有的钥匙里没有能打开该门的钥匙则跳过key|=Key[x][y];//更新已有钥匙的情况 if(vis[x][y][key])continue;//如果之前搜到过这个状态则跳过vis[x][y][key]=1;stp++;//可以则扩展q[++t]=(nod){x,y,key,stp};//保存当前坐标,以及钥匙与步伐情况 if(x==n&&y==m)return stp;//如果已经走到(n,m)则返回答案}}return -1;//无法抵达
}
int main(){pw[1]=1;for(int i=2;i<=15;++i)pw[i]=pw[i-1]<<1;//预处理pw数组scanf("%d%d%d",&n,&m,&p);scanf("%d",&tot);while(tot--){scanf("%d%d%d%d%d",&x,&y,&xx,&yy,&p);if(p==0){mp[x][y][xx][yy]=mp[xx][yy][x][y]=-1;}else {mp[x][y][xx][yy]=mp[xx][yy][x][y]=pw[p];//将门的标号更新到指定位置 }}int q; scanf("%d",&tot);while(tot--){scanf("%d%d%d",&x,&y,&q);Key[x][y]|=pw[q];//表示在(x,y)点上有编号为q的钥匙,将钥匙的编号更新到指定坐标 }cout<<bfs();return 0;
}

这个题我就用两个字形容:绝了
很久没有遇到这么好的题

P4011 孤岛营救问题相关推荐

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

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

  2. 洛谷 - P4011 孤岛营救问题(bfs+状态压缩)

    题目链接:点击查看 题目大意:给出一个n*m的迷宫,其中有一些边为不可逾越的墙,有一些边为不同型号的门,而钥匙会分布在迷宫的不同位置,求从点(1,1)到点(n,m)的最短时间 题目分析:出现在网络流里 ...

  3. 孤岛营救与汽车加油行驶问题

    题目链接:https://www.luogu.org/problemnew/show/P4011 (孤岛营救)|| https://www.luogu.org/problemnew/show/P400 ...

  4. 【线性规划与网络流24题】孤岛营救问题 分层图

    孤岛营救问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 1944年,特种兵麦克接到国防部的命令.要求马上赶赴太平洋上的一个孤岛,营救被敌军 ...

  5. [网络流24题-6]孤岛营救问题

    孤岛营救问题 为什么又是奇奇怪怪的混进来的题啊QAQ 又没想出网络流解法啊QAQ 看见P是10就又状压了吖QwQ bfs跑一遍就吼了w 为啥子网络流24题总是状压+最短路/bfs啊QAQ 哦对记得门和 ...

  6. c++ 孤岛营救问题

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

  7. 「网络流 24 题」孤岛营救问题

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

  8. 【CTSC1999】拯救大兵瑞恩(孤岛营救问题)

    2219 拯救大兵瑞恩 1999年CTSC国家队选拔赛 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description 1944年,特种兵麦克接到 ...

  9. [codevs 1911] 孤岛营救问题

    http://codevs.cn/problem/1911/ 题解: 这个题简单的做法就是建立分层图,还记得那篇 汽车加油行驶问题 吗?那是按照邮箱剩余油量建立分层图,而这个题要以获取钥匙的状态建立分 ...

最新文章

  1. oracle 条件查询,比较运算符,逻辑运算符,特殊运算符,判断空值,大小写敏感,多行,多列子查询...
  2. 【PAT乙级】1091 N-自守数 (15 分)
  3. 【竞赛相关】Kaggle竞赛宝典国内外竞赛方案汇总
  4. Java 获取Web项目相对webapp地址
  5. Javascript 获取字符串字节数的多种方法
  6. 软件定义无线电matlab书,软件定义无线电
  7. 再见DTC,你好Christmas Day
  8. mysql表空间预估_MYSQL实战优化——数据页、表空间
  9. android 注册静态广播接收器VS注册动态广播接收器
  10. 计算机领域CCF推荐会议列表
  11. NOIp2014 提高组 Day1 T1 生活大爆炸版石头剪刀布
  12. 【Excel2019(十五):条件格式与公式】【使用简单的条件格式+定义多重条件的条件格式+使用公式定义条件格式】
  13. [题目解析]乐乐的数字
  14. 解决IE11兼容HTML5 设置:设置兼容性视图网站正常显示网页
  15. linux--redis的安装和配置和开启多个端口
  16. 数据分析从0到1之AARRR模型 - Blog2
  17. 《C#零基础入门之百识百例》(五十八)接口 -- 模拟银行存储
  18. Windows电脑上那些为人熟知的视频剪辑调色应用
  19. 箭离开靶心是为了下一次更美丽的重逢
  20. 映美Jolimark FP-8800K+ 打印机驱动

热门文章

  1. 收藏 | 分享 3 种脑洞大开的Excel技巧
  2. 线程打印_面试题:用程序实现两个线程交替打印 0~100 的奇偶数
  3. easyui select ajax,easyui的combobox根据后台数据实现自动输入提示功能
  4. 面试难点!常用算法技巧之“滑动窗口”
  5. cent os重置mysql,linux mysql 能登陆不能修改用户(cent os 6.2)解决思路
  6. mysql判断表存在的sql语句_SQL 语句判断已知表是否存在_MySQL
  7. linux命令apprw,linux命令学习1(示例代码)
  8. tcp拥塞控制_网络TCP的拥塞控制算法简介
  9. linux如何使用vnc远程登录,如何使用Xmanager及VNC登录远程桌面
  10. core java面试题_CoreJava基础面试题