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

题目链接:https://www.luogu.org/problemnew/show/P4011

输入输出样例

输入样例#1:

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
输出样例#1:

14

题解:分层图最短路问题。最多就10类门,一看就是状态压缩最大空间 (1<<11)-1 ,很友好...d[i][sta]表示到点i,状态为sta的最短路长度(sta就是到i点前所持有的钥匙的状态)。

代码:

 #include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
#define CLR(a, b) memset((a), (b), sizeof((a)))
using namespace std;
const int N = ;
const int states = <<;
const int INF = 0x3f3f3f3f; int d[N][states], vis[N][states];
int id[N][N];
int key[N]; //key[i]:i点有哪些钥匙(状态)
int mp[N][N]; //mp[i][j]:i到j有哪类门
int dx[] = {, , -, };
int dy[] = {, , , -};
int n, m, p;
struct qnode{
int v;
int x;//状态
qnode(int _v=,int _x=):v(_v),x(_x){}
};
bool SPFA(int st, int ed) {
CLR(vis, );
CLR(d, INF);
d[st][] = ;
queue<qnode> q;
while(!q.empty()) q.pop();
q.push(qnode(st, ));
while(!q.empty()) {
qnode t = q.front(); q.pop();
int u = t.v;
int sta = t.x;
vis[u][sta] = false; if(key[u]) sta |= key[u];
for(int i = ; i < ; i++) {
int x = (u+m-)/m + dx[i];
int y = (u%m?u%m:m) + dy[i]; if(x < || x > n || y < || y > m) continue;
int v = id[x][y];
//不是墙 并且 有对应钥匙 或者没有门。
if(mp[u][v]!= && ( (sta&(<<mp[u][v])) || mp[u][v]==-)) {
if(d[v][sta] > d[u][t.x] + ) {
d[v][sta] = d[u][t.x] + ;
if(!vis[v][sta]) {
vis[v][sta] = true;
q.push(qnode(v, sta));
}
}
}
}
}
int ans = INF;
for(int i = ; i < states; ++i) ans = min(ans, d[ed][i]);
if(ans == INF) puts("-1");
else printf("%d\n", ans);
}
int main() {
int i, j, k, x1, y1, x2, y2, q, sum;
scanf("%d%d%d", &n, &m, &p);//行,列,门和墙的总数 int cnt = ;
for(i = ; i <= n; ++i)
for(j = ; j <= m; ++j) id[i][j] = ++cnt; CLR(mp, -);
scanf("%d", &k);//门和墙总数
for(i = ; i <= k; ++i) {
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &q);
int id1 = id[x1][y1];
int id2 = id[x2][y2];
mp[id1][id2] = mp[id2][id1] = q;
}
scanf("%d", &sum);//钥匙总数
for(i = ; i <= sum; ++i) {
scanf("%d%d%d", &x1, &y1, &q);
key[id[x1][y1]] |= (<<q);
}
SPFA(, n*m);
return ;
}

洛谷 P4011 孤岛营救问题【最短路+分层图】的更多相关文章

  1. 洛谷 [P4011] 孤岛营救问题

    状压+BFS 通过观察数据范围可知,我们应该状压钥匙种类,直接BFS即可 注意,一个点处可能不知有一把钥匙 #include <iostream> #include <cstdio& ...

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

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

  3. 洛谷 P4011 孤岛营救问题【bfs】

    注意: 一个点可能有多把钥匙,所以把每个点有钥匙的情况状压一下 两个点之间有障碍的情况只给出了单向,存的时候记得存一下反向 b[i][j]表示当前点拥有钥匙的状态,g[x1][y1][x2][y2]表 ...

  4. Luogu P4011 孤岛营救问题(状态压缩+最短路)

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

  5. 洛谷P4011 【网络流24题】 孤岛营救问题 (BFS+状压)

    一道妙题啊......(不知道为什么这道题的标签是网络流,不需要用网络流啊) 如果没有门和钥匙,连边(边权为1)求最短路就行了. 但是有这两个因素的限制,我们采用分层建图的思想,一共2p层,每层对应持 ...

  6. Luogu P4011 孤岛营救问题

    题目链接 \(Click\) \(Here\) 注意坑点:一个地方可以有多把钥匙. 被卡了一会,调出来发现忘了取出来实际的数字,直接把二进制位或上去了\(TwT\),其他的就是套路的分层图最短路.不算 ...

  7. 洛谷P4009 汽车加油行驶问题(分层最短路)

    传送门 说好的网络流24题呢……上次是状压dp,这次怎么又最短路了…… 不过倒是用这题好好学了一下分层图最短路 把每一个位置$(x,y)$,油量剩余$k$表示为一个状态,然后转化成一个$n$进制数,这 ...

  8. BZOJ:2763-[JLOI2011]飞行路线(最短路分层图)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2763 解题心得: 第一次见到分层最短路.其实题中说选择k条路径免费,那怎么选k条路径并没 ...

  9. P4011 孤岛营救问题

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

随机推荐

  1. cefsharp 在anycpu下运行

    从cefsharp57开始就支持anycpu了,不过需要一些设置: 1.首先要打开*.csprj文件,添加节点 <CefSharpAnyCpuSupport>true</CefSha ...

  2. 对象的深度拓展$.extend(true,{},a,b),深入理解,小心陷阱

    转载:https://www.cnblogs.com/DJeanWeb/p/4388689.html $.extend一般情景下,使用深度拓展两个对象时,我们想要的效果是,b对象覆盖掉a对象中存在的所 ...

  3. 数组的strong copy理解

      一.数组的不同情况下的copy,mutablecopy分析 1.不可变数组的copy(没有创建新对象,复制的只是指针)       2.不可变数组的mutable copy(创建新对象)     ...

  4. 前端开发实用工具-Bower的使用。

    参看博客:[https://segmentfault.com/a/1190000002971135]

  5. JAVA成员变量的隐藏

    一.如果子类与父类中有一个相同名称的成员变量,那么子类的成员变量会不会覆盖父类的成员变量?我们看下在的例子: public class A { public int x=10; } public cl ...

  6. LeetCode CombinationSum II

    class Solution { public: vector<vector<int> > combinationSum2(vector<int> &num ...

  7. :after伪类+content内容生成经典应用举例——张鑫旭

    一.简单说说content内容生成 content内容生成就是通过content属性生成内容,content属性早在CSS2.1的时候就被引入了,可以使用:before以及:after伪元素生成内容. ...

  8. javascript中让你捉摸不定的this

    this到底指向谁,估计很多人在使用javascript的过程中都遇到过,这个关键字如果没搞懂,在一些高级功能中都会困难重重,搜了下相关文章,介绍的都挺多的,也有很深入的,比如汤姆大叔的<深入理 ...

  9. Python的正则表达式与JSON

    Python的正则表达式需要导入re模块 菜鸟教程:http://www.runoob.com/python/python-reg-expressions.html 官方文档:https://docs ...

  10. L3(SP+OO+UT)能力评估