网络流24题14孤岛营救问题

Posted 租酥雨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流24题14孤岛营救问题相关的知识,希望对你有一定的参考价值。

题面戳我
题面想放就放啦~

sol

状压当前已获得的钥匙状态,每次与门判一下子集关系,\(BFS\)即可。

code

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 20;
int door[N][N][4],key[N][N];
int n,m,p,k,s,dep[N][N][1<<10],ans;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
struct zt{int x,y,t;};
queue<zt>Q;
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
int main()
{
    n=gi();m=gi();p=gi();
    k=gi();
    while (k--)
    {
        int x1=gi(),y1=gi(),x2=gi(),y2=gi(),d1,d2,G=gi();
        if (x2==x1+1) d1=0,d2=2;
        if (y2==y1+1) d1=1,d2=3;
        if (x2==x2-1) d1=2,d2=0;
        if (y2==y1-1) d1=3,d2=1;
        door[x1][y1][d1]=door[x2][y2][d2]=G?(1<<G-1):(-1);
    }
    s=gi();
    while (s--)
    {
        int x=gi(),y=gi(),Q=gi();
        key[x][y]|=1<<Q-1;
    }
    Q.push((zt){1,1,0});
    dep[1][1][0]=1;
    while (!Q.empty())
    {
        int x=Q.front().x;
        int y=Q.front().y;
        int t=Q.front().t;Q.pop();
        for (int k=0;k<4;k++)
        {
            int i=x+dx[k],j=y+dy[k];
            if (i<1||i>n||j<1||j>m) continue;
            int b=t|door[x][y][k],r=t|key[i][j];
            if (b^t||dep[i][j][r]) continue;
            dep[i][j][r]=dep[x][y][t]+1;Q.push((zt){i,j,r});
        }
    }
    ans=1e9;
    for (int i=(1<<p)-1;i;i--)
        if (dep[n][m][i])
            ans=min(ans,dep[n][m][i]-1);
    printf("%d\n",ans==1e9?-1:ans);
    return 0;
}

以上是关于网络流24题14孤岛营救问题的主要内容,如果未能解决你的问题,请参考以下文章

网络流24题 No.14 孤岛营救问题 (分层图最短路)

[CTSC 1999]拯救大兵瑞恩&[网络流24题]孤岛营救问题

网络流24题

网络流 24 题 解题报告

网络流 24 题 解题报告

网络流24题(好大的坑啊)