luogu P4011 孤岛营救问题

又是简单的状压BFS,直接代码

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;

const int maxm = 12;

const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};

struct Node {
    int x, y, steps, state;
};

int G[maxm][maxm][maxm][maxm], num[maxm][maxm], key[maxm][maxm][maxm], n, m;
bool vis[maxm][maxm][(1<<10)+5];

bool valid(int x1, int y1, int x2, int y2, int state) {
    if(x2<1||x2>n||y2<1||y2>m) return false;
    if(G[x1][y1][x2][y2] == -1) return false;
    if(G[x1][y1][x2][y2] == 0 || (G[x1][y1][x2][y2]&state)) return true;
    return false;
}

int solve() {
    queue<Node> q;
    int startstate = 0;
    for(int i = 0; i < num[1][1]; ++i)
        startstate |= key[1][1][i];
    q.push(Node{1, 1, 0, startstate});
    vis[1][1][startstate] = true;
    while(!q.empty()) {
        auto now = q.front();q.pop();
        if(now.x == n && now.y == m) return now.steps;
        for(int i = 0; i < 4; ++i) {
            int nx = now.x + dx[i], ny = now.y + dy[i];
            if(!valid(now.x,now.y,nx,ny,now.state))continue;
            int newstate = now.state;
            for(int j = 0; j < num[nx][ny]; ++j)
                newstate |= key[nx][ny][j];
            if(vis[nx][ny][newstate]) continue;
            vis[nx][ny][newstate] = true;
            q.push(Node{nx, ny, now.steps+1, newstate});
        }
    }
    return -1;
}

void run_case() {
    int p, k, x1, x2, y1, y2, g, s;
    cin >> n >> m >> p >> k;
    for(int i = 0; i < k; ++i) {
        cin >> x1 >> y1 >> x2 >> y2 >> g;
        if(g == 0) G[x1][y1][x2][y2] = G[x2][y2][x1][y1] = -1;
        else G[x1][y1][x2][y2] = G[x2][y2][x1][y1] = 1<<(g-1);
    }
    cin >> s;
    for(int i = 0; i < s; ++i) {
        cin >> x1 >> y1 >> p;
        key[x1][y1][num[x1][y1]++] = 1<<(p-1);
    }
    cout << solve();
}


int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    run_case();
    cout.flush();
    return 0;
}
View Code

 

posted @ 2020-02-07 21:12  GRedComeT  阅读(109)  评论(0编辑  收藏  举报