NOIP2013 华容道

传送门

分析

暴力能拿 \(60\) ~ \(70pts\)

具体的...以后再更吧

代码

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 1e7
#define il inline
#define re register
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;

template <typename T> inline void read(T &x) {
    T f = 1; x = 0; char c;
    for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;
    for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    x *= f;
}

struct edge {
    int to, nxt, val;
} e[40010];

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

int n, m, q, ans;
int head[4005], cnt;
int g[33][33], qx[1003], qy[1003], dis[35][35], d[4011];
bool vis[4011];

void insert(int u, int v, int w) {
    e[++cnt].to = v, e[cnt].val = w, e[cnt].nxt = head[u], head[u] = cnt;
}

void bfs(int sx, int sy, int tx, int ty, int opt) {
    memset(dis, 0, sizeof(dis));
    int head = 1, tail = 1, x, y;
    qx[1] = sx, qy[1] = sy, dis[sx][sy] = 1;
    while (head <= tail) {
        x = qx[head], y = qy[head];
        for (int i = 0; i < 4; ++i) {
            int nx = x + dx[i], ny = y + dy[i];
            if (g[nx][ny] && !dis[nx][ny] && (nx != tx || ny != ty))
                qx[++tail] = nx, qy[tail] = ny, dis[nx][ny] = dis[x][y] + 1;
        }
        ++head;
    }
    if (opt == 4) return;
    for (int i = 0; i < 4; ++i) {
        int nx = tx + dx[i], ny = ty + dy[i];
        if ((nx != sx || ny != sy) && dis[nx][ny])
            insert(tx*120 + ty*4 + opt, tx*120 + ty*4 + i, dis[nx][ny] - 1);
    }
    insert(tx*120 + ty*4 + opt, sx*120 + sy*4 + opt ^ 1, 1);
}

void SPFA(int tx, int ty) {
    for (int i = 0; i <= 4000; ++i) d[i] = INF, vis[i] = 0;
    queue <int> q;
    for (int i = 0; i < 4; ++i) {
        int nx = tx + dx[i], ny = ty + dy[i], nd = tx*120 + ty*4 + i;
        if (dis[nx][ny]) {
            d[nd] = dis[nx][ny] - 1;
            q.push(nd); vis[nd] = 1;
        }
    }
    while (!q.empty()) {
        int u = q.front(); q.pop(); vis[u] = 0;
        for (int i = head[u]; i >= 0; i = e[i].nxt) {
            int v = e[i].to, w = e[i].val;
            if (d[u] + w < d[v]) {
                d[v] = d[u] + w;
                if (!vis[v]) {q.push(v); vis[v] = 1;}
            }
        }
    }
}

int main() {
    memset(head, -1, sizeof(head));
    read(n), read(m), read(q);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            read(g[i][j]);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            if (g[i][j]) {
                if (g[i-1][j]) bfs(i - 1, j, i, j, 0);
                if (g[i+1][j]) bfs(i + 1, j, i, j, 1);
                if (g[i][j-1]) bfs(i, j - 1, i, j, 2);
                if (g[i][j+1]) bfs(i, j + 1, i, j, 3);
            }
    int ex, ey, sx, sy, tx, ty;
    while (q--) {
        ans = INF;
        read(ex), read(ey), read(sx), read(sy), read(tx), read(ty);
        if (sx == tx && sy == ty) {puts("0"); continue;}
        bfs(ex, ey, sx, sy, 4);
        SPFA(sx, sy);
        for (int i = 0; i < 4; ++i) ans = min(ans, d[tx*120 + ty*4 +i]);
        if (ans >= INF) puts("-1");
        else printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hlw1/p/11437369.html