제출 #1350950

#제출 시각아이디문제언어결과실행 시간메모리
1350950msab3fPark (BOI16_park)C++20
100 / 100
535 ms57696 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long double ld;

const int MAX_N = 2000 + 10;

int n, m, w, h, dp[4][MAX_N], mx[4][4];
vector<pair<int, int>> adj[MAX_N], mst_adj[MAX_N];
bitset<MAX_N> mark;

struct Tree {
    int x, y, r;
} arr[MAX_N];

void add_edge(vector<pair<int, int>> g[], int u, int v, int w) {
    g[u].push_back({v, w});
    g[v].push_back({u, w});
}

void prim() {
    priority_queue<pair<int, pair<int, int>>> q;
    auto add = [&] (int u) {
        mark[u] = true;
        for (auto [v, w] : adj[u])
            if (!mark[v])
                q.push({-w, {u, v}});
    };
    add(0);
    while (!q.empty()) {
        auto [w, uv] = q.top(); q.pop(); auto [u, v] = uv;
        if (mark[v]) continue;
        add_edge(mst_adj, u, v, -w);
        add(v);
    }
}

void dfs(int u, int p, int dp[]) {
    for (auto [v, w] : mst_adj[u])
        if (v != p) {
            dp[v] = max(dp[u], w);
            dfs(v, u, dp);
        }
}

int main() {
    cin >> n >> m >> w >> h;

    for (int i = 0; i < n; ++i)
        cin >> arr[i].x >> arr[i].y >> arr[i].r;

    for (int u = 0; u < n; ++u) {
        auto [x, y, r] = arr[u];
        add_edge(adj, 0, u + 4, y - r);
        add_edge(adj, 1, u + 4, w - x - r);
        add_edge(adj, 2, u + 4, h - y - r);
        add_edge(adj, 3, u + 4, x - r);
        for (int v = u + 1; v < n; ++v) {
            auto [vx, vy, vr] = arr[v];   
            add_edge(adj, u + 4, v + 4, floor(sqrt(pow<ld, ld>(x - vx, 2) + pow<ld, ld>(y - vy, 2)) - r - vr));
        }
    }

    prim();

    for (int u = 0; u < 4; ++u) {
        dfs(u, -1, dp[u]);
        dp[u][u] = 1e9;
    }

    for (int u = 0; u < 4; ++u) {
        for (int v = 0; v < 4; ++v) {
            mx[u][v] = 1e9;
            vector<int> a, b;
            for (int x = 0; x < 4; ++x) {
                if ((x + 4 - u) % 4 < (x + 4 - v) % 4)
                    a.push_back(x);
                else
                    b.push_back(x);
                }
            for (int x : a)
                for (int y : b)
                    mx[u][v] = min(mx[u][v], dp[x][y]);
        }
    }

    while (m--) {
        int r, e;
        cin >> r >> e;
        --e;
        for (int x = 0; x < 4; ++x)
            if (mx[e][x] >= 2 * r)
                cout << x + 1;
        cout << '\n';
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...