网络流24题 之十四 孤岛营救问题 分层图
2015-12-26 20:25
651 查看
题目大意:一张网格图,上面有一些点可能有某种钥匙。节点和节点之间可能有门。有些门须要特定的钥匙就能够通过,有些不管怎样都过不去。求从(1,1)開始到(m,n)的最短时间。
思路:分层图+状态压缩。
f[i][j][k],当中i和j描写叙述的是当前所在的位置。k是压缩了的当前有哪些钥匙(因为钥匙的数量<=10,所以全部的状态1<<10的空间内就能够搞定)。然后向四个方向更新的时候推断能否经过门。
CODE:
思路:分层图+状态压缩。
f[i][j][k],当中i和j描写叙述的是当前所在的位置。k是压缩了的当前有哪些钥匙(因为钥匙的数量<=10,所以全部的状态1<<10的空间内就能够搞定)。然后向四个方向更新的时候推断能否经过门。
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 20 #define INF 0x3f3f3f3f using namespace std; const int dx[] = {0,1,-1,0,0}; const int dy[] = {0,0,0,1,-1}; struct Complex{ int x,y,status; Complex(int _,int __,int ___):x(_),y(__),status(___) {} Complex() {} }; int m,n,p,doors,keys; int f[MAX][MAX][1 << 11]; bool v[MAX][MAX][1 << 11]; int map[MAX][MAX][MAX][MAX]; int key[MAX][MAX]; void SPFA(); inline bool Accelerator(int x1,int y1,int x2,int y2,int status); int main() { cin >> m >> n >> p >> doors; memset(map,-1,sizeof(map)); for(int a,b,c,d,x,i = 1;i <= doors; ++i) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&x); map[a][b][c][d] = map[c][d][a][b] = x; } cin >> keys; for(int x,y,z,i = 1;i <= keys; ++i) { scanf("%d%d%d",&x,&y,&z); key[x][y] |= 1 << z; } SPFA(); int ans = INF; for(int i = 0;i < (1 << 11); ++i) ans = min(ans,f[m] [i]); if(ans == INF) ans = -1; cout << ans << endl; return 0; } void SPFA() { memset(f,0x3f,sizeof(f)); f[1][1][0] = 0; static queue<Complex> q; while(!q.empty()) q.pop(); q.push(Complex(1,1,0)); while(!q.empty()) { Complex now = q.front(); q.pop(); v[now.x][now.y][now.status] = false; int _status = now.status; if(key[now.x][now.y]) _status |= key[now.x][now.y]; for(int i = 1;i <= 4; ++i) { int fx = now.x + dx[i]; int fy = now.y + dy[i]; if(!fx || !fy || fx > m || fy > n) continue; if(Accelerator(now.x,now.y,fx,fy,_status)) if(f[fx][fy][_status] > f[now.x][now.y][now.status] + 1) { f[fx][fy][_status] = f[now.x][now.y][now.status] + 1; if(!v[fx][fy][_status]) v[fx][fy][_status] = true,q.push(Complex(fx,fy,_status)); } } } } inline bool Accelerator(int x1,int y1,int x2,int y2,int status) { int need_key = map[x1][y1][x2][y2]; if(!need_key) return false; if(need_key == -1) return true; return (status >> need_key)&1; }
相关文章推荐
- TCP简介
- AsyncHttpClient
- linux内核ipv4网络部分分层结构及涉入源文件
- 使用HTTP访问网络
- Caffe 抽取CNN网络特征 Python
- linux 内核网络,数据接收流程图
- 计算机网络的基本概念
- reachbility检测网络变化
- TCP三次握手
- Linux网络基本管理
- java web基础 --- 图像加载Http请求
- Volley-----网络请求框架
- 对网络基本情况进行查看方法
- URL,data(网络下载,url编码,文件读写),NSFileManager(文件管理者,系统单例)
- http://blog.sina.com.cn/s/blog_ad1c3bdf0102uz99.html
- 脚本开发工具—快速自制TC防破解网络验证注册码系统
- TCP长连接与短连接的区别
- 网络爬虫Heritrix1.14.4在MyEclipse中的安装配置与使用教程
- CentOS的网络配置简析
- centos 网络配置