Submission #1303403

#TimeUsernameProblemLanguageResultExecution timeMemory
1303403chaitanyamehtaTowers (NOI22_towers)C++20
0 / 100
709 ms150844 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long

struct Edge {
    int v;
    int id;
};

void dfs1(int u, vector<int> &vis, vector<int> &par_edge, const vector<vector<Edge>> &g) {
    vis[u] = 1;
    for (const Edge &e : g[u]) {
        int vv = e.v;
        if (e.id == par_edge[u]) continue; // skip parent edge
        if (!vis[vv]) {
            par_edge[vv] = e.id;
            dfs1(vv, vis, par_edge, g);
        }
    }
}

void dfs2(int u, vector<int> &vis, vector<int> &par_edge, vector<int> &used, vector<int> &deg, const vector<vector<Edge>> &g) {
    vis[u] = 1;
    for (const Edge &e : g[u]) {
        int v = e.v;
        if (vis[v] || par_edge[v] != e.id) continue; // only traverse child-side tree edges
        dfs2(v, vis, par_edge, used, deg, g);
        if (!used[e.id] && deg[u] < 2 && deg[v] < 2) {
            used[e.id] = 1;
            deg[u]++; deg[v]++;
        }
    }
}

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

    int n;
    if (!(cin >> n)) return 0;

    vector<int> x(n), y(n);
    for (int i = 0; i < n; ++i) cin >> x[i] >> y[i];

    // coordinate compression
    vector<int> xs = x, ys = y;
    sort(xs.begin(), xs.end());
    xs.erase(unique(xs.begin(), xs.end()), xs.end());
    sort(ys.begin(), ys.end());
    ys.erase(unique(ys.begin(), ys.end()), ys.end());

    int nx = (int)xs.size();
    int ny = (int)ys.size();
    int V = nx + ny;

    vector<int> cx(n), cy(n);
    for (int i = 0; i < n; ++i) {
        cx[i] = (lower_bound(xs.begin(), xs.end(), x[i]) - xs.begin());
        cy[i] = (lower_bound(ys.begin(), ys.end(), y[i]) - ys.begin()) + nx;
    }

    // adjacency sized to actual number of vertices
    vector<vector<Edge>> g(V);
    for (int i = 0; i < n; ++i) {
        g[cx[i]].push_back({cy[i], i});
        g[cy[i]].push_back({cx[i], i});
    }

    // arrays sized to V or n (not hard-coded large constants)
    vector<int> vis(V, 0);
    vector<int> par_edge(V, -1);
    vector<int> deg(V, 0);
    vector<int> used(n, 0);

    // DFS #1: build spanning forest and fill par_edge (edge id for child)
    for (int i = 0; i < V; ++i) {
        if (!vis[i]) dfs1(i, vis, par_edge, g);
    }

    // Select cycle (non-tree) edges if they don't violate deg <= 2
    for (int i = 0; i < n; ++i) {
        int u = cx[i], v = cy[i];
        // If the edge i is not the tree edge of either endpoint, it's a non-tree (cycle) edge
        if (par_edge[u] != i && par_edge[v] != i) {
            if (deg[u] < 2 && deg[v] < 2) {
                used[i] = 1;
                deg[u]++; deg[v]++;
            }
        }
    }

    // DFS #2 (postorder): process tree edges
    fill(vis.begin(), vis.end(), 0);
    for (int i = 0; i < V; ++i) {
        if (!vis[i]) dfs2(i, vis, par_edge, used, deg, g);
    }

    // Output
    for (int i = 0; i < n; ++i) cout << used[i];
    cout << '\n';
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...