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

题目链接:https://www.luogu.org/recordnew/show/10464387

【问题分析】

分层图最短路径问题。

【建模方法】

用P位二进制表示当前获得的钥匙状态,建立2^P层图。每层图表示在当前钥匙状态下的地图,每获得一把钥匙进入新的一层,BFS求最短路即可。

明明就是状压+BFS为什么会出现在网络流24题里???

#include 
#include 
#include 
 
using namespace std;
 
struct node
{
    int step,x,y,state;
    //分别记录格子的坐标,步数,有哪些钥匙
    node(){}
    node(int _x,int _y,int _step,int _state)
    {
        x = _x,y = _y;
        step = _step,state = _state;
    }
};
int n,m,p;
int mp[51][51][51][51];//记录地图信息
int to[4][2] = {1,0,0,1,-1,0,0,-1};
int key[51][51];//每一个格子的钥匙有哪些
bool vis[51][51][1 << 10];//标记格子状态,避免重复访问
 
bool judge(int x,int y)
{
    if(x <= 0 || y <= 0 || x > n || y > m) {
        return 0;
    }
    return 1;
}
void BFS()
{
    struct node now,next;
    memset(vis,0,sizeof(vis));
    queue q;
    q.push(node(1,1,0,key[1][1]));
    vis[1][1][key[1][1]] = 1;
 
    while(!q.empty()) {
        now = q.front();
        q.pop();
 
        for(int i = 0; i < 4; i++) {
            next.x = now.x + to[i][0];
            next.y = now.y + to[i][1];
            next.state = now.state | key[next.x][next.y];
            next.step = now.step + 1;
            if(!judge(next.x,next.y)) continue;
            //格子的状态是否被访问过
            if(vis[next.x][next.y][next.state]) continue;
            int ty = mp[now.x][now.y][next.x][next.y];
            //是否为墙
            if(ty == 0) continue;
            //是否有门的钥匙
            if(ty > 0 && !((next.state >> (ty - 1)) & 1)) continue;
            vis[next.x][next.y][next.state] = 1;
            if(next.x == n && next.y == m) {
                printf("%d\n",next.step);
                return;
            }
            q.push(next);
        }
    }
    printf("-1\n");
}
int main(void)
{
    int x1,y1,x2,y2,ty;
    int num;
    while(scanf("%d%d%d",&n,&m,&p) != EOF) {
        memset(mp,-1,sizeof(mp));
        memset(key,0,sizeof(key));
        scanf("%d",&num);
        while(num--) {
            scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&ty);
            mp[x1][y1][x2][y2] = ty;
            mp[x2][y2][x1][y1] = ty;
        }
        scanf("%d",&num);
        while(num--) {
            scanf("%d%d%d",&x1,&y1,&ty);
            key[x1][y1] |= (1 << (ty - 1));
        }
        BFS();
    }
    return 0;
}

 

你可能感兴趣的:(ACM-图论)