답안 #556482

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
556482 2022-05-03T08:47:53 Z alextodoran Wall (CEOI14_wall) C++17
100 / 100
291 ms 22936 KB
/**
 ____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int D_MAX = 400;

const int U = 0, R = 1, D = 2, L = 3;
const int UL = 0, UR = 1, DR = 2, DL = 3;

int N, M;

bool village[D_MAX][D_MAX];

int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int cost[D_MAX + 1][D_MAX + 1][4];
bool isPoint (int x, int y) {
    return (0 <= x && x <= N && 0 <= y && y <= M);
}

int backdir[D_MAX + 1][D_MAX + 1];

ll dist[D_MAX + 1][D_MAX + 1];
bool seen[D_MAX + 1][D_MAX + 1];
void minDistTree () {
    for (int x = 0; x <= N; x++) {
        for (int y = 0; y <= M; y++) {
            dist[x][y] = LLONG_MAX;
            seen[x][y] = false;
            backdir[x][y] = -1;
        }
    }
    priority_queue <tuple <ll, int, int>> q;

    dist[0][0] = 0;
    q.push(make_tuple(-dist[0][0], 0, 0));
    while (q.empty() == false) {
        ll d; int x, y; tie(d, x, y) = q.top();
        q.pop();
        if (seen[x][y] == true) {
            continue;
        }
        seen[x][y] = true;
        for (int dir = 0; dir < 4; dir++) {
            int x1 = x + dx[dir], y1 = y + dy[dir];
            if (isPoint(x1, y1) == true && dist[x][y] + cost[x][y][dir] < dist[x1][y1]) {
                backdir[x1][y1] = (dir + 2) % 4;
                dist[x1][y1] = dist[x][y] + cost[x][y][dir];
                q.push(make_tuple(-dist[x1][y1], x1, y1));
            }
        }
    }
}

bool edge[D_MAX + 1][D_MAX + 1][4];

void addEdge (int x, int y, int dir) {
    edge[x][y][dir] = true;
    edge[x + dx[dir]][y + dy[dir]][(dir + 2) % 4] = true;
}

ll cdist[D_MAX + 1][D_MAX + 1][4];
bool cseen[D_MAX + 1][D_MAX + 1][4];
ll solve () {
    for (int x = 0; x <= N; x++) {
        for (int y = 0; y <= M; y++) {
            for (int c = 0; c < 4; c++) {
                cdist[x][y][c] = LLONG_MAX;
                cseen[x][y][c] = false;
            }
        }
    }
    priority_queue <tuple <ll, int, int, int>> q;

    function <void (int, int, int, int, int, int, int)>
        update = [&] (int x1, int y1, int c1, int x2, int y2, int c2, int cost) {
        if (isPoint(x2, y2) == true && cdist[x1][y1][c1] + cost < cdist[x2][y2][c2]) {
            cdist[x2][y2][c2] = cdist[x1][y1][c1] + cost;
            q.push(make_tuple(-cdist[x2][y2][c2], x2, y2, c2));
        }
    };

    cdist[0][0][UL] = LLONG_MIN;
    cdist[0][0][UR] = 0;
    q.push(make_tuple(-cdist[0][0][UR], 0, 0, UR));
    while (q.empty() == false) {
        ll d; int x, y, c; tie(d, x, y, c) = q.top();
        q.pop();
        if (cseen[x][y][c] == true) {
            continue;
        }
        cseen[x][y][c] = true;
        if (edge[x][y][c] == false) {
            update(x, y, c, x, y, (c + 1) % 4, 0);
        }
        if (edge[x][y][(c + 3) % 4] == false) {
            update(x, y, c, x, y, (c + 3) % 4, 0);
        }
        update(x, y, c, x + dx[c], y + dy[c], (c + 3) % 4, cost[x][y][c]);
        update(x, y, c, x + dx[(c + 3) % 4], y + dy[(c + 3) % 4], (c + 1) % 4, cost[x][y][(c + 3) % 4]);
    }
    return cdist[0][0][DL];
}

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> N >> M;
    for (int x = 0; x < N; x++) {
        for (int y = 0; y < M; y++) {
            cin >> village[x][y];
        }
    }
    for (int x = 0; x < N; x++) {
        for (int y = 0; y <= M; y++) {
            cin >> cost[x][y][D];
            cost[x + 1][y][U] = cost[x][y][D];
        }
    }
    for (int x = 0; x <= N; x++) {
        for (int y = 0; y < M; y++) {
            cin >> cost[x][y][R];
            cost[x][y + 1][L] = cost[x][y][R];
        }
    }

    minDistTree();
    for (int x = 0; x < N; x++) {
        for (int y = 0; y < M; y++) {
            if (village[x][y] == true) {
                int x1 = x, y1 = y;
                while (backdir[x1][y1] != -1) {
                    int dir = backdir[x1][y1];
                    int x2 = x1 + dx[dir], y2 = y1 + dy[dir];
                    addEdge(x1, y1, dir);
                    x1 = x2; y1 = y2;
                }
                addEdge(x, y, R);
                addEdge(x, y, D);
                addEdge(x + 1, y, R);
                addEdge(x, y + 1, D);
            }
        }
    }

    cout << solve() << "\n";

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 468 KB Output is correct
2 Correct 1 ms 468 KB Output is correct
3 Correct 1 ms 468 KB Output is correct
4 Correct 1 ms 468 KB Output is correct
5 Correct 1 ms 468 KB Output is correct
6 Correct 1 ms 852 KB Output is correct
7 Correct 2 ms 852 KB Output is correct
8 Correct 2 ms 848 KB Output is correct
9 Correct 1 ms 724 KB Output is correct
10 Correct 2 ms 852 KB Output is correct
11 Correct 2 ms 980 KB Output is correct
12 Correct 2 ms 980 KB Output is correct
13 Correct 3 ms 1108 KB Output is correct
14 Correct 4 ms 1108 KB Output is correct
15 Correct 2 ms 980 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 980 KB Output is correct
2 Correct 2 ms 1108 KB Output is correct
3 Correct 3 ms 1112 KB Output is correct
4 Correct 3 ms 1108 KB Output is correct
5 Correct 3 ms 1108 KB Output is correct
6 Correct 3 ms 1112 KB Output is correct
7 Correct 3 ms 1108 KB Output is correct
8 Correct 2 ms 980 KB Output is correct
9 Correct 2 ms 1108 KB Output is correct
10 Correct 3 ms 1132 KB Output is correct
11 Correct 3 ms 1108 KB Output is correct
12 Correct 2 ms 1108 KB Output is correct
13 Correct 2 ms 1108 KB Output is correct
14 Correct 2 ms 1108 KB Output is correct
15 Correct 3 ms 1108 KB Output is correct
16 Correct 4 ms 1108 KB Output is correct
17 Correct 3 ms 1108 KB Output is correct
18 Correct 3 ms 1108 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 70 ms 6060 KB Output is correct
2 Correct 47 ms 5204 KB Output is correct
3 Correct 41 ms 5460 KB Output is correct
4 Correct 56 ms 7576 KB Output is correct
5 Correct 128 ms 9728 KB Output is correct
6 Correct 55 ms 5980 KB Output is correct
7 Correct 142 ms 10180 KB Output is correct
8 Correct 124 ms 9420 KB Output is correct
9 Correct 102 ms 9796 KB Output is correct
10 Correct 136 ms 12312 KB Output is correct
11 Correct 144 ms 14900 KB Output is correct
12 Correct 39 ms 5904 KB Output is correct
13 Correct 127 ms 9780 KB Output is correct
14 Correct 218 ms 12548 KB Output is correct
15 Correct 243 ms 12568 KB Output is correct
16 Correct 196 ms 13536 KB Output is correct
17 Correct 250 ms 18240 KB Output is correct
18 Correct 291 ms 22936 KB Output is correct
19 Correct 268 ms 15152 KB Output is correct
20 Correct 207 ms 13324 KB Output is correct