CSES - HIIT Open 2024 - Results
Submission details
Task:Budgetting bridges
Sender:Barren plateau
Submission time:2024-11-16 15:01:55 +0200
Language:C++ (C++17)
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.00 sdetails
#2ACCEPTED0.00 sdetails
#3ACCEPTED0.00 sdetails
#4ACCEPTED0.00 sdetails
#5ACCEPTED0.00 sdetails
#6ACCEPTED0.32 sdetails
#7ACCEPTED0.35 sdetails
#8ACCEPTED0.35 sdetails
#9ACCEPTED0.31 sdetails
#10ACCEPTED0.36 sdetails
#11ACCEPTED0.49 sdetails

Code

#include <bits/stdc++.h>
using namespace std;

using Z = long long int;

struct Edge {
    Z v;
    Z w;
    Z c;
};

Z n, m, k;
vector<Edge> edges;

vector<bool> ret;

struct Level {
    Z c;
    vector<pair<Z, Z>> edges;
    vector<pair<Z, pair<Z, Z>>> plans;
};
vector<Level> levels;

struct UnionFind {
    UnionFind(Z n) : parent(n) {
        for(Z i = 0; i < n; ++i) {
            parent[i] = i;
        }
    }

    Z find(Z x) {
        if(parent[x] != x) {
            log.push_back({x, parent[x]});
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    void merge(Z x, Z y) {
        x = find(x);
        y = find(y);
        if(parent[x] != y) {
            log.push_back({x, parent[x]});
            parent[x] = y;
        }
    }

    void reset(Z logPos) {
        if(logPos > (Z)log.size()) {
            throw 5;
        }

        for(Z i = (Z)log.size() - 1; i >= logPos; --i) {
            parent[log[i].first] = log[i].second;
        }
        log.resize(logPos);
    }

    vector<Z> parent;
    vector<pair<Z, Z>> log;
};

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

    cin >> n >> m >> k;

    edges.resize(m);
    map<pair<Z, Z>, Z> lookup;
    for(Z i = 0; i < m; ++i) {
        Edge edge;
        cin >> edge.v >> edge.w >> edge.c;
        --edge.v;
        --edge.w;
        lookup[{edge.v, edge.w}] = edge.c;
        edges.push_back(edge);
    }

    ret.resize(n, true);

    std::sort(edges.begin(), edges.end(), [&](const Edge& a, const Edge& b) { return a.c < b.c; });
    for(const Edge& edge : edges) {
        if(levels.empty() || levels.back().c != edge.c) {
            levels.push_back({edge.c});
        }
        levels.back().edges.push_back({edge.v, edge.w});
    }

    for(Z i = 0; i < k; ++i) {
        Z b;
        cin >> b;

        for(Z j = 0; j < b; ++j) {
            Z v, w;
            cin >> v >> w;
            --v;
            --w;
            auto it = lookup.find({v, w});
            if(it == lookup.end()) throw 5;
            Z c = it->second;

            Z A = 0;
            Z B = (Z)levels.size() - 1;
            while(A != B) {
                Z M = (A + B) / 2;
                if(levels[M].c < c) {
                    A = M + 1;
                } else {
                    B = M;
                }
            }
            if(levels[A].c != c) throw 5;
            levels[A].plans.push_back({i, {v, w}});
        }
    }

    UnionFind uf(n);
    for(Level& level : levels) {
        std::sort(level.plans.begin(), level.plans.end());

        Z logPos = (Z)uf.log.size();
        Z ci = -1;
        for(auto elem : level.plans) {
            if(elem.first != ci) {
                uf.reset(logPos);
            }
            ci = elem.first;
            auto [v, w] = elem.second;
            if(uf.find(v) == uf.find(w)) {
                ret[ci] = false;
            }
            uf.merge(v, w);
        }
        uf.reset(logPos);

        for(auto p : level.edges) {
            uf.merge(p.first, p.second);
        }
    }

    for(Z i = 0; i < k; ++i) {
        cout << (ret[i] ? "YES" : "NO") << "\n";
    }

    return 0;
}

Test details

Test 1

Verdict: ACCEPTED

input
3 3 2
1 2 1
1 3 1
2 3 2
1
...

correct output
YES
NO

user output
YES
NO

Test 2

Verdict: ACCEPTED

input
3 3 2
1 2 1
1 3 1
2 3 1
3
...

correct output
NO
YES

user output
NO
YES

Test 3

Verdict: ACCEPTED

input
10 20 10
5 10 1
10 1 1
4 10 1
3 1 1
...

correct output
YES
YES
YES
YES
YES
...

user output
YES
YES
YES
YES
YES
...

Test 4

Verdict: ACCEPTED

input
10 20 10
5 2 1
10 6 3
5 4 1
2 3 3
...

correct output
NO
NO
YES
NO
NO
...

user output
NO
NO
YES
NO
NO
...

Test 5

Verdict: ACCEPTED

input
10 20 10
6 1 3
9 3 1
9 5 4
1 2 1
...

correct output
YES
YES
NO
NO
NO
...

user output
YES
YES
NO
NO
NO
...

Test 6

Verdict: ACCEPTED

input
100000 200000 50
96703 90063 1
17270 97269 1
71482 60904 1
59756 21609 1
...

correct output
YES
YES
YES
YES
YES
...

user output
YES
YES
YES
YES
YES
...

Test 7

Verdict: ACCEPTED

input
100000 200000 30000
22200 5519 1
83133 20672 1
91862 97945 1
8983 61175 1
...

correct output
YES
YES
YES
YES
YES
...

user output
YES
YES
YES
YES
YES
...

Test 8

Verdict: ACCEPTED

input
100000 200000 5000
22200 5519 9
83133 20672 4
91862 97945 5
8983 61175 4
...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...

Test 9

Verdict: ACCEPTED

input
100000 200000 5000
22200 5519 9
83133 20672 4
91862 97945 5
8983 61175 4
...

correct output
YES
NO
NO
YES
YES
...

user output
YES
NO
NO
YES
YES
...

Test 10

Verdict: ACCEPTED

input
100000 200000 2000
22200 5519 870732304
83133 20672 363736896
91862 97945 488411190
8983 61175 396736607
...

correct output
NO
NO
NO
NO
NO
...

user output
NO
NO
NO
NO
NO
...

Test 11

Verdict: ACCEPTED

input
100000 200000 60000
22200 5519 9
83133 20672 4
91862 97945 5
8983 61175 4
...

correct output
NO
NO
YES
NO
NO
...

user output
NO
NO
YES
NO
NO
...