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

如果没有门和钥匙,连边(边权为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. SQL基本概念和SQL通用语法

    SQL 1.什么是SQL? Structured Query Language:结构化查询语句 其实就是定义了操作所有关系型数据库的规则.每一种数据库操作的方式存在不一样的地方称为"方言&q ...

  2. linux 安装redis及问题收集

    contos 7 下安装redis教程可参照https://www.cnblogs.com/hxun/p/11075755.html值得注意的是在第6步方法一(所以建议使用方法二),如果直接使用xft ...

  3. 特殊的阻塞队列 - java.util.concurrent.SynchronousQueue 分析

    描述 SynchrounousQueue 是一个比较特殊的无界阻塞队列并支持非公平和公平模式,严格意义上来说不算一个队列,因为它不像其他阻塞队列一样能有容量,它仅有一个指向栈顶的地址,栈中的节点由线程 ...

  4. 你的工具包已到货「GitHub 热点速览 v.22.31」

    如果你经常用 shell 记得看看本周特推里的 gum,它能给你的 shell 增加新趣味.除了这个 shell kit,我们还有 dashboard kit--tabler,功能技能 kit eng ...

  5. 秋季招聘季如何制作一款“秀色可餐”的简历?由ShareLatex和Python3打造

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_161 秋招季还有两个月就到了,即所谓的"金九银十".疫情因素导致市场环境不太理想,所以我们更应该未焚而徙薪,未 ...

  6. 基于ABP和Magicodes实现Excel导出操作

      前端使用的vue-element-admin框架,后端使用ABP框架,Excel导出使用的Magicodes.IE.Excel.Abp库.Excel导入和导出操作几乎一样,不再介绍.文本主要介绍E ...

  7. 关于奉加微PHY62xx系列如何选型?PHY6222/PHY6212/PHY6252

    PHY6252是一款支持BLE 5.2功能的系统级芯片(SOC),集成了低功耗的高性能多模射频收发机,搭载32位高性能低功耗处理器,提供64K retention SRAM.可选512/256K Fl ...

  8. 我与Apache DolphinScheduler的成长之路

    关于 Apache DolphinScheduler社区 Apache DolphinScheduler(incubator) 于17年在易观数科立项,19年3月开源, 19 年8月进入Apache ...

  9. .NET WebAPI 采用 IDistributedCache 实现分布式缓存过滤器 Redis 模式

    分布式缓存是由多个应用服务器共享的缓存,通常作为访问它的应用服务器的外部服务进行维护. 分布式缓存可以提高 ASP.NET Core 应用的性能和可伸缩性,尤其是当应用由云服务或服务器场托管时. 与其 ...

  10. 贪吃蛇(C语言版)链表实现

    贪吃蛇 gitee:贪吃蛇C语言版: Snake 蛇的结构 typedef struct Snake { int x; int y; struct Snake *next; }; 游戏开始欢迎界面 / ...