一道妙题啊......(不知道为什么这道题的标签是网络流,不需要用网络流啊)

如果没有门和钥匙,连边(边权为1)求最短路就行了。

但是有这两个因素的限制,我们采用分层建图的思想,一共2p层,每层对应持有钥匙的2p种状态(就是状态压缩),在分层图上连边,当前层没有的钥匙,就向有该类钥匙的层连边(注意此时的边权是0)。最后宽搜求最短路就行了,答案是每层图终点取最小值。

  1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=1e6;
4 int first[N],to[N],w[N],nxt[N],tot;
5 struct node{
6 int x,y;
7 }key[15][20];//存钥匙
8 int n,M,row,line,keyn;
9 int layer,r,num[20][20];
10 int fg[200][200],kn[15],dis[102500];
11 int q[N],inf=0x3f3f3f3f;
12 bool vis[102500];
13
14 void add(int x,int y,int z){
15 nxt[++tot]=first[x];first[x]=tot;
16 to[tot]=y;w[tot]=z;
17 }
18
19 void build(){
20 int i,j,k,x,y,t;
21 bool havekey[15]={0};
22 M=row*line;//每层节点数
23 layer=1<<keyn;//总层数
24 n=layer*M;//总结点数
25 for(k=0;k<layer;k++){//对每层处理
26 for(i=1;i<=keyn;i++)
27 if(k&(1<<(i-1))) havekey[i]=true;
28 else havekey[i]=false;//该层有哪几类钥匙
29 for(i=1;i<=row;i++)
30 for(j=1;j<=line;j++){
31 x=num[i][j];y=num[i][j+1];//向右连边
32 if(y!=0&&fg[x][y]!=-1)
33 if(fg[x][y]==0||havekey[fg[x][y]]){
34 add(k*M+x,k*M+y,1);
35 add(k*M+y,k*M+x,1);
36 }
37 y=num[i+1][j];//向左连边
38 if(y!=0&&fg[x][y]!=-1)
39 if(fg[x][y]==0||havekey[fg[x][y]]){
40 add(k*M+x,k*M+y,1);
41 add(k*M+y,k*M+x,1);
42 }
43 }
44 for(i=1;i<=keyn;i++)//当前层没有钥匙,转移到有该类钥匙的层
45 if(!havekey[i]){
46 t=k+(1<<(i-1));//t表示有第i类钥匙的层
47 for(j=1;j<=kn[i];j++){
48 x=num[key[i][j].x][key[i][j].y];
49 add(k*M+x,t*M+x,0);//注意连边的权值是0
50 }
51 }
52 }
53 }
54
55 void Read(){
56 int i,j,k,x,y,p;
57 cin>>row>>line>>keyn>>r;k=0;
58 for(i=1;i<=row;i++)
59 for(j=1;j<=line;j++) num[i][j]=++k;//编号
60 for(i=1;i<=r;i++){
61 scanf("%d%d",&x,&y);j=num[x][y];
62 scanf("%d%d",&x,&y);k=num[x][y];
63 cin>>p;if(p==0) p=-1;//表示墙
64 fg[j][k]=fg[k][j]=p;//有门/墙
65 }
66 cin>>r;
67 for(i=1;i<=r;i++){
68 scanf("%d%d%d",&x,&y,&p);
69 kn[p]++;
70 key[p][kn[p]].x=x;
71 key[p][kn[p]].y=y;//第p类钥匙的第kn[p]把的位置
72 }
73 }
74
75 void SPFA(){
76 int i,j,k,head,tail;
77 for(i=1;i<=n;i++) dis[i]=inf;
78 dis[1]=0,vis[1]=true,q[1]=1;
79 head=tail=1;
80 while(head<=tail){
81 i=q[head];
82 for(k=first[i];k;k=nxt[k]){
83 j=to[k];
84 if(dis[j]>dis[i]+w[k]){
85 dis[j]=dis[i]+w[k];
86 if(!vis[j]){
87 q[++tail]=j;vis[j]=true;
88 }
89 }
90 }
91 vis[i]=false,head++;
92 }
93 }
94
95 void solve(){
96 int i,ans=inf,T;
97 SPFA();
98 T=num[row][line];
99 for(i=0;i<layer;i++)
100 ans=min(ans,dis[i*M+T]);
101 if(ans==inf) cout<<-1<<endl;
102 else cout<<ans<<endl;
103 }
104
105 int main(){
106 Read();//读入数据
107 build();//建图
108 solve();
109 return 0;
110 }

重点还是在于建图。。。

洛谷P4011 【网络流24题】 孤岛营救问题 (BFS+状压)的更多相关文章

  1. [洛谷P3254] [网络流24题] 圆桌游戏

    Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n) ...

  2. [CTSC 1999]拯救大兵瑞恩&[网络流24题]孤岛营救问题

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

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

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

  4. [洛谷P4012] [网络流24题] 深海机器人问题

    Description 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生 ...

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

    https://loj.ac/problem/6121 BFS + 状压 写过就好想,注意细节debug #include <bits/stdc++.h> #define read rea ...

  6. 【洛谷4011】孤岛营救问题(状压SPFA)

    点此看题面 大致题意: 有一个\(N*M\)的四联通迷宫,相邻两个可能互通,可能有一扇门,也可能有一堵墙.对于第\(i\)类的门,你需要有第\(i\)类的钥匙才可以通过.问你从\((1,1)\)到达\ ...

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

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

  8. 洛谷 P7718 -「EZEC-10」Equalization(差分转化+状压 dp)

    洛谷题面传送门 一道挺有意思的题,现场切掉还是挺有成就感的. 首先看到区间操作我们可以想到差分转换,将区间操作转化为差分序列上的一个或两个单点操作,具体来说我们设 \(b_i=a_{i+1}-a_i\ ...

  9. 2018.10.27 洛谷P2915奶牛混合起来Mixed Up Cows(状压dp)

    传送门 状压dp入门题. 按照题意建一个图. 要求的就是合法的链的总数. 直接f[i][j]f[i][j]f[i][j]表示当前状态为jjj,下一位要跟iii连起来的方案数. 然后从没被选并且跟iii ...

  10. 洛谷P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows 状压动归

    考场上空间开大了一倍就爆0了QAQ- Code: #include<cstdio> #include<algorithm> #include<cmath> usin ...

随机推荐

  1. 那些舍不得删除的 MP3--批量修改mp3的ID3tag

    整理电脑时发现很多mp3.那是大约2001年至2009年之间.那个时候大家听歌,还是习惯从网上下载mp3.虽然现在听歌比从前方便多了,简单到只需在APP中输入歌名,但用播放器听mp3的感觉是完全不同的 ...

  2. java反射的初理解

    反射 获取类的方法: Class<?> aClass1 = Class.forName("TestDemo.refection.User");//通过类路径获取 Cla ...

  3. react学习1-jsx语法注意点

    * 1.定义虚拟DOM不要写引号 * 2.标签中使用js表达式的时候,要使用{} * 3.样式类名指定要使用className * 4.要使用内联样式的话,要使用style={{key:"v ...

  4. 达人专栏 | 还不会用 Apache Dolphinscheduler?大佬用时一个月写出的最全入门教程【三】

    作者 | 欧阳涛 招联金融大数据开发工程师 02 Master启动流程 2.10 WorkFlowExecutorThread 里执行 Submit StandByTask 方法 SubmitStan ...

  5. Apache DolphinScheduler & Doris 将于本周六联合进行线上 Meetup

    01 - 活动介绍 2020年,大数据成为国家基建的一个重要组成,大数据在越来越多的领域展现威力.随着大数据的应用场景越来越多,大家对数据的响应速度和数据加工工作流的方便程度也提出了更高的要求.在这种 ...

  6. java-异常处理和线程的一些简单方法及使用

    1.1 子类重写父类含有throws声明异常抛出的方法时的规则: 1.允许不再抛出任何异常. 2.仅抛出部分异常. 3.抛出父类方法抛出异常的子类型异常. 4.不可以抛出额外异常. 5.不能抛出父类方 ...

  7. 记录一个i变量引发的事故

    概述 近期开发中遇到一个特别的问题,觉得很有必要与你下来.就是由于在开发中一个很小的疏忽,导致了很大的问题,是什么呢? 现象 我的程序突然引发了v8内部的错误,提示都是c++的,如下.程序一启动就直接 ...

  8. Python之验证码识别功能

    Python之pytesseract 识别验证码 1.验证码来一个 2.适合什么样的验证码呢? 只能识别简单.静态.无重叠.只有数字字母的验证码 3.实际应用:模拟人工登录.页面内容识别.爬虫抓取信息 ...

  9. github action 实现CI/CD

    两种github action 打包.Net Core 项目docker镜像推送到阿里云镜像仓库 1.GitHub Actions 是什么? 大家知道,持续集成由很多操作组成,比如抓取代码.运行测试. ...

  10. AXI MCDMA 仿真与工作流程分析

    说明 关于背景知识,可以先看 https://www.cnblogs.com/xingce/p/16386108.html 引用一段官方的说明,AXI MCDMA存在的主要目的是为了节约资源,我们想要 ...