답안 #563814

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
563814 2022-05-18T07:11:03 Z piOOE Pipes (CEOI15_pipes) C++17
40 / 100
5000 ms 19116 KB
#include <bits/stdc++.h>

using namespace std;

#define all(x) begin(x), end(x)
#define sz(x) ((int)size(x))
#define trace(x) cout << #x << ": " << (x) << endl;

typedef long long ll;

const int N = 100000, M = 6000000;

struct dsu {
    int p[N];

    dsu() = default;

    dsu(int n) {
        iota(p, p + n, 0);
    }

    void init(int n) {
        iota(p, p + n, 0);
    }

    int get(int a) {
        int x = a;
        while (p[a] != a) {
            a = p[a];
        }
        while (x != a) {
            int v = p[x];
            p[x] = a;
            x = v;
        }
        return a;
    }

    bool same(int a, int b) {
        return get(a) == get(b);
    }

    bool mrg(int a, int b) {
        a = get(a), b = get(b);
        if (a == b) return false;
        p[b] = a;
        return true;
    }
};

vector<pair<int, int>> g[N];

//binary jumps with O(n) memory
//https://peltorator.ru/posts/linear_binups/

int jump[N], parent[N], depth[N], id_p[N];

int lca(int a, int b) {
    if (depth[a] < depth[b]) swap(a, b);
    while (depth[a] > depth[b]) {
        if (depth[jump[a]] >= depth[b]) {
            a = jump[a];
        } else {
            a = parent[a];
        }
    }
    while (a != b) {
        if (jump[a] != jump[b]) {
            a = jump[a];
            b = jump[b];
        } else {
            a = parent[a];
            b = parent[b];
        }
    }
    return a;
}

void add_leaf(int v, int par) {
    assert(par != -1 && par != v);
    parent[v] = par;
    depth[v] = depth[par] + 1;
    if (depth[par] - depth[jump[par]] == depth[jump[par]] - depth[jump[jump[par]]]) {
        jump[v] = jump[jump[par]];
    } else {
        jump[v] = par;
    }
}

int A[N], B[N], sz[N];
bool usedE[N];
//used edges

dsu d1, d2;
//d1 is just our tree, d2 is for merging in a path

void dfs(int v, int par, int id) {
    add_leaf(v, par);
    d2.p[v] = v;
    id_p[v] = id;
    for (auto [to, i]: g[v]) {
        if (to != par) {
            dfs(to, v, i);
        }
    }
}

void union_path(int a, int b) {
    int c = lca(a, b);
    while (depth[a = d2.get(a)] > depth[c]) {
        usedE[id_p[a]] = true;
        d2.mrg(parent[a], a);
    }
    while (depth[b = d2.get(b)] > depth[c]) {
        usedE[id_p[b]] = true;
        d2.mrg(parent[b], b);
    }
}

void merge(int a, int b, int idx) {
    int pa = d1.get(a);
    int pb = d1.get(b);
    if (sz[pa] < sz[pb]) {
        swap(a, b);
        swap(pa, pb);
    }
    g[a].emplace_back(b, idx);
    g[b].emplace_back(a, idx);
    dfs(b, a, idx);
    d1.mrg(pa, pb);
    sz[pa] += sz[pb];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    iota(jump, jump + N, 0);
    iota(parent, parent + N, 0);
    int n, m;
    cin >> n >> m;
    d1.init(n);
    d2.init(n);
    int idx = 0;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        if (d1.same(a, b)) {
            union_path(a, b);
        } else {
            A[idx] = a, B[idx] = b;
            merge(a, b, idx);
            ++idx;
        }
    }
    for (int i = 0; i < idx; ++i) {
        if (!usedE[i]) {
            cout << A[i] + 1 << " " << B[i] + 1 << '\n';
        }
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 3412 KB Output is correct
2 Correct 2 ms 3412 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 64 ms 3732 KB Output is correct
2 Correct 27 ms 3668 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 156 ms 3668 KB Output is correct
2 Correct 125 ms 3688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 576 ms 4096 KB Output is correct
2 Correct 320 ms 4116 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2994 ms 5088 KB Output is correct
2 Runtime error 1895 ms 19116 KB Memory limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5067 ms 7340 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5066 ms 7880 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5092 ms 8608 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5078 ms 8676 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5066 ms 8272 KB Time limit exceeded
2 Halted 0 ms 0 KB -