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

如果没有门和钥匙,连边(边权为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. BufferedInputStream字节缓冲输入流

    package com.yang.Test.BufferedStudy; import java.io.BufferedInputStream; import java.io.FileInputStr ...

  2. 字符串的操作和MAth工具类

    字符串的操作 常用方法 判断功能方法 equals(String s)判断两个字符串是否相同,区分大小写 equsalsignorecase(String s) 判断两个字符串是否相同,不区分大小写 ...

  3. HashSet集合的介绍和哈希值

    java.util.Set接口 extends Collection接口 Set接口的特点: 1.不允许存储重复的元素 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历 java.uti ...

  4. 关于char[]数组通过scanf赋值使用上的一些问题。。

    关于char[]数组通过scanf赋值使用上的一些问题. 假如我们有这么一段代码 #include <stdio.h> int main(void){ char c1[2]; scanf( ...

  5. YII的lazy loading

    版本1 require('class\class1.php'); require('class\class1.php'); if($is_girl){ echo 'this is a girl'; $ ...

  6. 承上启下继往开来,Python3上下文管理器(ContextManagers)与With关键字的迷思

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_217 在开发过程中,我们会经常面临的一个常见问题是如何正确管理外部资源,比如数据库.锁或者网络连接.稍不留意,程序将永久保留这些资 ...

  7. CSS3 基础学习

    CSS基础学习 当前进度[P78] 参考资料 视频链接:https://www.bilibili.com/video/BV14J4114768 菜鸟教程:https://www.runoob.com/ ...

  8. 开发Chrome插件,实现网站自动登录

    近期被一个事情困扰着,我们采购了一款软件,里面有一个数据大屏页,当登录过期后,数据就会保持原状,不再更新.和供应商反馈了很多次,都无法彻底解决数据显示的问题,没办法,自己周末在家研究,网站自动登录的事 ...

  9. Spring源码环境搭建

    Spring源码在github上,地址是https://github.com/spring-projects/spring-framework/,选择5.3.x版本,直接从github上克隆项目网速很 ...

  10. 技术管理进阶——技术Leader需要数据思维

    原创不易,求分享.求一键三连 假设我长得很漂亮,拥有众多追求者,但是初出闺房的我对这世界上的男人毫无认知,那么该如何选择呢?这真是一个问题! 妈妈说,愿意为我花钱的男人未必爱我,但不愿意为我花钱的男人 ...