Submission #1352516

#TimeUsernameProblemLanguageResultExecution timeMemory
1352516vjudge1Park (BOI16_park)C++17
0 / 100
177 ms33392 KiB
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>

using namespace std;

struct Tree {
    long long x, y, r;
};

struct Edge {
    int u, v;
    double dist;
    bool operator<(const Edge& other) const {
        return dist < other.dist;
    }
};

struct Visitor {
    int r, e, id;
};

struct DSU {
    vector<int> parent;
    DSU(int n) {
        parent.resize(n);
        for (int i = 0; i < n; ++i) parent[i] = i;
    }
    int find(int i) {
        if (parent[i] == i) return i;
        return parent[i] = find(parent[i]);
    }
    void unite(int i, int j) {
        int root_i = find(i);
        int root_j = find(j);
        if (root_i != root_j) parent[root_i] = root_j;
    }
    bool connected(int i, int j) {
        return find(i) == find(j);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    long long w, h;
    cin >> n >> m >> w >> h;

    vector<Tree> trees(n);
    for (int i = 0; i < n; ++i) {
        cin >> trees[i].x >> trees[i].y >> trees[i].r;
    }

    vector<Edge> edges;
    for (int i = 0; i < n; ++i) {
        edges.push_back({i + 4, 0, (double)trees[i].x - trees[i].r});
        edges.push_back({i + 4, 1, (double)trees[i].y - trees[i].r}); 
        edges.push_back({i + 4, 2, (double)w - trees[i].x - trees[i].r}); 
        edges.push_back({i + 4, 3, (double)h - trees[i].y - trees[i].r}); 
    }

    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            long long dx = trees[i].x - trees[j].x;
            long long dy = trees[i].y - trees[j].y;
            double d = sqrt((double)dx * dx + (double)dy * dy);
            edges.push_back({i + 4, j + 4, d - trees[i].r - trees[j].r});
        }
    }

    sort(edges.begin(), edges.end());

    vector<Visitor> visitors(m);
    for (int i = 0; i < m; ++i) {
        cin >> visitors[i].r >> visitors[i].e;
        visitors[i].id = i;
    }

    auto visitors_sorted = visitors;
    sort(visitors_sorted.begin(), visitors_sorted.end(), [](const Visitor& a, const Visitor& b) {
        return a.r < b.r;
    });

    DSU dsu(n + 4);
    int edge_ptr = 0;
    vector<string> results(m);

    for (const auto& v : visitors_sorted) {
        while (edge_ptr < edges.size() && edges[edge_ptr].dist < 2.0 * v.r) {
            dsu.unite(edges[edge_ptr].u, edges[edge_ptr].v);
            edge_ptr++;
        }

        bool can_move[5][5] = {false};
        for(int i=1; i<=4; ++i) can_move[i][i] = true;

        if (!dsu.connected(1, 0) && !dsu.connected(1, 2) && !dsu.connected(1, 3)) 
            can_move[1][2] = can_move[2][1] = true;
        if (!dsu.connected(2, 1) && !dsu.connected(2, 3) && !dsu.connected(2, 0)) 
            can_move[2][3] = can_move[3][2] = true;
        if (!dsu.connected(3, 2) && !dsu.connected(3, 0) && !dsu.connected(3, 1)) 
            can_move[3][4] = can_move[4][3] = true;
        if (!dsu.connected(0, 3) && !dsu.connected(0, 1) && !dsu.connected(0, 2)) 
            can_move[4][1] = can_move[1][4] = true;

        vector<bool> reachable(5, false);
        vector<int> q;
        q.push_back(v.e);
        reachable[v.e] = true;
        int head = 0;
        while(head < q.size()){
            int curr = q[head++];
            for(int next=1; next<=4; ++next){
                if(can_move[curr][next] && !reachable[next]){
                    reachable[next] = true;
                    q.push_back(next);
                }
            }
        }

        string res = "";
        for (int i = 1; i <= 4; ++i) if (reachable[i]) res += to_string(i);
        results[v.id] = res;
    }

    for (const auto& res : results) cout << res << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...