답안 #1018469

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1018469 2024-07-10T05:52:05 Z caterpillow Domino (COCI15_domino) C++17
160 / 160
922 ms 80512 KB
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pl = pair<ll, ll>;
using pi = pair<int, int>;
#define vt vector
#define f first
#define s second
#define pb push_back
#define all(x) x.begin(), x.end() 
#define size(x) ((int) (x).size())
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define ROF(i, a, b) for (int i = (b) - 1; i >= (a); i--)
#define F0R(i, b) FOR (i, 0, b)
#define endl '\n'
const ll INF = 1e18;
const int inf = 1e9;

template<template<typename> class Container, typename T>
ostream& operator<<(ostream& os, Container<T> o) {
    os << "{"; 
    int g = size(o); 
    for (auto i : o) os << i << ((--g) == 0 ? "" : ", "); 
    os << "}";
    return os;
}

void _print() {
    cerr << "\n";
}

template<typename T, typename ...V>
void _print(T t, V... v) {
    cerr << t; if (sizeof...(v)) cerr << ", "; _print(v...);
}

#ifdef LOCAL
#define dbg(x...) cerr << #x << " = "; _print(x);
#else
#define dbg(x...)
#define cerr if (0) std::cerr
#endif

/*

max cost max flow?

*/

int n, k; 
vt<vt<int>> grid;
bool flo[2000][2000][5]; // direction index, then to source/sink

const int dr[4] = {0, 1, 0, -1}, dc[4] = {1, 0, -1, 0};
int enc(int r, int c) {
    return r * n + c;
}
pi dec(int id) {
    return {id / n, id % n};
}
bool valid(int r, int c) {
    return r >= 0 && c >= 0 && r < n && c < n;
}

// sink goes to even r + c
// you never go to the source twice
int find_augmenting_path() {
    vt<int> par(n * n, -1); // direction taken to reach here
    vt<int> dist(n * n, inf);
    vt<bool> in_queue(n * n);
    queue<pi> q;

    int ans = inf;
    pi best;

    F0R (r, n) {
        F0R (c, n) {
            if ((r + c) % 2 == 0) {
                if (!flo[r][c][4]) {
                    int id = enc(r, c);
                    in_queue[id] = true;
                    q.push({r, c});
                    dist[id] = grid[r][c];
                    par[id] = -1;
                }
            }
        }
    }

    while (!q.empty()) {
        auto [r, c] = q.front(); q.pop();
        int id = r * n + c;
        in_queue[id] = false;
        if ((r + c) % 2 == 0) { // lhs
            F0R (i, 4) {
                int nr = r + dr[i];
                int nc = c + dc[i];
                if (valid(nr, nc)) {
                    if (!flo[r][c][i]) { // no flow
                        int vid = enc(nr, nc);
                        if (dist[id] < dist[vid]) {
                            dist[vid] = dist[id];
                            par[vid] = i;
                            if (!in_queue[vid]) {
                                q.push({nr, nc});
                                in_queue[vid] = true;
                            }
                        }
                    }
                }
            }
        } else { // rhs
            F0R (i, 4) {
                int nr = r + dr[i];
                int nc = c + dc[i];
                if (valid(nr, nc)) {
                    if (flo[nr][nc][(i + 2) % 4]) { // yes flow
                        int vid = enc(nr, nc);
                        if (dist[id] < dist[vid]) {
                            dist[vid] = dist[id];
                            par[vid] = i;
                            if (!in_queue[vid]) {
                                q.push({nr, nc});
                                in_queue[vid] = true;
                            }
                        }
                    }
                }
            }
            if (!flo[r][c][4]) { // check flow to sink
                if (dist[id] + grid[r][c] < ans) {
                    ans = dist[id] + grid[r][c];
                    best = {r, c};
                } 
            }
        }
    }
    auto [r, c] = best;
    flo[r][c][4] = 1;
    while (par[enc(r, c)] != -1) {
        int id = enc(r, c);
        int i = (par[id] + 2) % 4; // direction from current to prev
        int pr = r + dr[i];
        int pc = c + dc[i];
        if ((r + c) % 2 == 0) { // lhs
            flo[r][c][i] = 0; // took a backedge
        } else { // rhs
            flo[pr][pc][par[id]] = 1; // took a normal edge
        }
        r = pr;
        c = pc;
    }
    flo[r][c][4] = 1;
    return ans;
}

main() {
    cin.tie(0)->sync_with_stdio(0);
    
    cin >> n >> k;
    grid.resize(n, vt<int>(n));
    ll tot = 0;
    F0R (r, n) {
        F0R (c, n) {
            cin >> grid[r][c];
            tot += grid[r][c];
            grid[r][c] = 1000 - grid[r][c];
        }
    }
    int flow = 0;
    F0R (i, k) flow += find_augmenting_path();
    int ans = 2 * k * 1000 - flow;
    cout << tot - ans << endl;
}

Compilation message

domino.cpp:159:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  159 | main() {
      | ^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 4440 KB Output is correct
2 Correct 17 ms 4396 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 352 ms 64548 KB Output is correct
2 Correct 323 ms 80480 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 253 ms 36408 KB Output is correct
2 Correct 207 ms 36404 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 130 ms 16724 KB Output is correct
2 Correct 109 ms 16452 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 653 ms 64812 KB Output is correct
2 Correct 546 ms 76448 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 724 ms 64816 KB Output is correct
2 Correct 597 ms 80512 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 604 KB Output is correct
2 Correct 4 ms 604 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 868 ms 64528 KB Output is correct
2 Correct 687 ms 80408 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 348 KB Output is correct
2 Correct 2 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 233 ms 16448 KB Output is correct
2 Correct 229 ms 16468 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 922 ms 64532 KB Output is correct
2 Correct 781 ms 80296 KB Output is correct