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

注意:

  • 一个点可能有多把钥匙,所以把每个点有钥匙的情况状压一下
  • 两个点之间有障碍的情况只给出了单向,存的时候记得存一下反向

b[i][j]表示当前点拥有钥匙的状态,g[x1][y1][x2][y2]表示两点之间门的类型(0表示没有,-1表示墙比较方便),f[i][j][k]表示点(i,j)在拥有k状态钥匙的情况下的最小步数,v[i][j][k]表示f[i][j][k]的状态是否在bfs队列里。然后转移比较类似spfa

以及终于知道为什么这种题会在24题里了…因为24全名“网络流与线性规划二十四题”…

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int inf=1e9,dx[]={1,-1,0,0},dy[]={0,0,-1,1};
int n,m,p,t,s,g[15][15][15][15],b[15][15],f[15][15][20005];
bool v[15][15][20005];
struct qwe
{
    int x,y,s;
}now;
int read()
{
    int r=0,f=1;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
    {
        if(p==‘-‘)
            f=-1;
        p=getchar();
    }
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r*f;
}
int main()
{
    n=read(),m=read(),p=read(),t=read();
    for(int i=1;i<=t;i++)
    {
        int x1=read(),y1=read(),x2=read(),y2=read(),z=read();
        z=z==0?-1:z;
        g[x1][y1][x2][y2]=z;g[x2][y2][x1][y1]=z;
    }
    s=read();
    for(int i=1;i<=s;i++)
    {
        int x=read(),y=read(),z=read();
        b[x][y]=b[x][y]|(1<<z);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            for(int k=0;k<(1<<14);k++)
                f[i][j][k]=inf;
    queue<qwe>q;
    now.x=1,now.y=1,now.s=b[1][1];
    f[1][1][now.s]=0;
    v[1][1][now.s]=1;
    q.push(now);
    while(!q.empty())
    {
        int x=q.front().x,y=q.front().y,z=q.front().s;
        v[x][y][z]=0;
        q.pop();
        for(int i=0;i<4;i++)
        {
            int x1=x+dx[i],y1=y+dy[i];
            if(x1<1||x1>n||y1<1||y1>m||g[x][y][x1][y1]==-1||(g[x][y][x1][y1]>0&&!((1<<g[x][y][x1][y1])&z)))
                continue;
            int w=z|b[x1][y1];//cout<<x1<<" "<<y1<<" "<<w<<" "<<f[x1][y1][w]<<endl;
            if(f[x1][y1][w]>f[x][y][z]+1)
            {
                f[x1][y1][w]=f[x][y][z]+1;
                if(!v[x1][y1][w])
                {
                    now.x=x1,now.y=y1,now.s=w;
                    v[x1][y1][w]=1;
                    q.push(now);
                }
            }
        }
    }
    int ans=inf;
    for(int i=0;i<(1<<14);i++)
        ans=min(ans,f[n][m][i]);
    printf("%d\n",ans==inf?-1:ans);
    return 0;
}

原文地址:https://www.cnblogs.com/lokiii/p/8439723.html

时间: 2024-10-10 00:48:21

洛谷 P4011 孤岛营救问题【bfs】的相关文章

洛谷 [P4011] 孤岛营救问题

状压+BFS 通过观察数据范围可知,我们应该状压钥匙种类,直接BFS即可 注意,一个点处可能不知有一把钥匙 #include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> #include <queue> using namespace std; bool f[14][14][1200]; int n,m,p,k,s,key[15][15],block1[

洛谷 1144 最短路计数 bfs

洛谷1144 最短路计数 传送门 其实这道题目的正解应该是spfa里面加一些处理,,然而,,然而,,既然它是无权图,,那么就直接bfs了,用一个cnt记录一下每一个点的方案数,分几种情况讨论一下转移,最后输出cnt即为结果.. 题目中所说的重边和自环啥的没看出来有啥影响.. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int maxn = 100000 + 500;

洛谷 P1162 填充颜色 (BFS)

这道题的核心就是找到一个被"1"围起来的"0",找到以后这道题就是个水题. 我的方法十分无脑,如果这个"0"被"1"围起来了,那么它的四周无论多远(<n)一定有"1".所以这道题就可以开心的枚举了(),最差时间复杂度O(n^3),实际要比这跑得快. #include<iostream> #include<cstdio> using namespace std; int map[

洛谷 P1379 八数码难题 Label:判重&amp;&amp;bfs

特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数

洛谷 P1126 机器人搬重物 (BFS)

题目链接:https://www.luogu.org/problemnew/show/P1126 吐槽:这题很阴险 一开始没把格子图转化成点图:30分 转化成点图,发现样例过不去,原来每步要判断vis数组和step大小,寻找最优解,一块加了上去,以为能AX,结果边界处理不对:50分 加了边界后才AC. (实际修改过程要坑爹的多orz 这么说吧,从20分到100分我全得过) 言归正传,搞一下这道题 广搜题,思路很好想:用结构体开个队列,分别保存每步的坐标.方向和步数,用vis数组保存当前格子上的最

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可

洛谷 P3227 BZOJ 3144 [HNOI2013]切糕

题目描述 经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B.出于美观考虑,小 A 希望切面能尽量光滑且和谐.于是她找到你,希望你能帮她找出最好的切割方案. 出于简便考虑,我们将切糕视作一个长 P.宽 Q.高 R 的长方体点阵.我们将位于第 z层中第 x 行.第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的点称为(x,y,z),它有一个非负的不和谐值 v(x,y,z).一个合法的切面满足以下两个条件: 与每个纵轴(一共有 P*Q 个纵轴)有且

洛谷P1519 穿越栅栏 Overfencing

P1519 穿越栅栏 Overfencing 69通过 275提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 USACO是100分,洛谷是20分 为什么只有十分 题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路.给定迷宫的宽度W(1<=W<=38)及高度H(1<=H&

洛谷OJ P1379 八数码难题 解题报告

洛谷OJ P1379 八数码难题 解题报告 by MedalPluS 题目描述   在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变.   输入格式   输入初试状态,一行九个数字,空格用0表示   输出格式 只有一行,该行只有一个数字,表示从初始状态到