[网络流24题]孤岛营救问题

本文介绍了一个迷宫最短路径问题的解决方法,使用广度优先搜索结合状态压缩来处理包含钥匙和门的复杂迷宫环境,实现从起点(1,1)到终点(n,n)的路径寻找。

链接

题意:走迷宫问题,从(1,1)到(n,n)的最短时间,其中有墙,钥匙和门的设定。

做法:

广度优先搜索+钥匙串状态压缩

Q:可这和网络流有什么关系

A:标签:网络流24题,没了

UGLY Code:

#include<bits/stdc++.h>
#define N 200
using namespace std;
int n,m,p,s,k;
bool vis[15][15][1<<11];
int wall[15][15][15][15];
int key[15][15][15],sum[15][15];
int dox[4]={0,-1,0,1},doy[4]={1,0,-1,0};

template <class T>
void read(T &x)
{
    char c;int sign=1;
    while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
}

struct Node { int x,y,dis,key; };

int bfs()
{
    memset(vis,0,sizeof(vis));
    int k=0;for(int i=1;i<=sum[1][1];++i) k|=(1<<key[1][1][i]);
    queue<Node> q;
    q.push((Node){1,1,0,k});
    while(!q.empty())
    {
        Node u=q.front();q.pop();
        int x=u.x,y=u.y,d=u.dis,k=u.key;
        if(x==n&&y==m) return d;
        if(vis[x][y][k]) continue;
        vis[x][y][k]=1;
        for(int i=0;i<4;++i)
        {
            int dx=x+dox[i],dy=y+doy[i];
            if(dx<1||dy<1||dx>n||dy>m) continue;
            if(wall[x][y][dx][dy]==-1||(k>>wall[x][y][dx][dy]&1))
            {
                int bt=k;
                for(int j=1;j<=sum[dx][dy];++j) k|=(1<<key[dx][dy][j]);
                q.push((Node){dx,dy,d+1,k});
                k=bt;
            }
        }
    }
    return -1;
}
int main()
{
    memset(wall,-1,sizeof(wall));
    read(n);read(m);read(p);
    read(k);
    for(int i=1;i<=k;++i)
    {
        int x1,y1,x2,y2,opt;
        read(x1);read(y1);read(x2);read(y2);read(opt);
        wall[x1][y1][x2][y2]=wall[x2][y2][x1][y1]=opt;
    }
    read(s);
    for(int i=1;i<=s;++i)
    {
        int x,y,z;
        read(x);read(y);read(z);
        key[x][y][++sum[x][y]]=z;
    }
    cout<<bfs()<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/Chtholly/p/10665844.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值