Submission #1264169

#TimeUsernameProblemLanguageResultExecution timeMemory
1264169VMaksimoski008시간이 돈 (balkan11_timeismoney)C++20
45 / 100
2096 ms60128 KiB
#include <bits/stdc++.h>
#define ar array
#define int long long

using namespace std;

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

const int mod = 1e9 + 7;
const ll inf = 1e9;
const int N = 1e5 + 5;

struct union_find {
    int n;
    vector<int> par, size;

    union_find(int _n) : n(_n), par(n+1), size(n+1, 1) {
        for(int i=1; i<=n; i++) par[i] = i;
    }

    int find(int u) {
        if(u == par[u]) return u;
        return par[u] = find(par[u]);
    }

    bool uni(int a, int b) {
        a = find(a); b = find(b);
        if(a == b) return 0;
        if(size[a] < size[b]) swap(a, b);
        size[a] += size[b];
        par[b] = a;
        return 1;
    }
};

struct point {
    ll x, y;
    bool operator<(const point &b) {
        return x * y < b.x * b.y;
    }
    bool operator==(const point &b) {
        return x == b.x && y == b.y;
    }
};

int n, m;
vector<ar<int, 4> > edg;
vector<pii> used;

point mst(ll A, ll B) {
    ll T=0, C=0;
    union_find dsu(n);

    sort(edg.begin(), edg.end(), [&](const ar<int, 4> &x, const ar<int, 4> &y) {
        return A * x[2] + B * x[3] < A * y[2] + B * y[3]; 
    });

    used.clear();
    for(auto [a, b, t, c] : edg) {
        if(dsu.uni(a, b)) {
            T += t;
            C += c;
            used.push_back({ a, b });
        }
    }
    return { T, C };
}

signed main() {
    ios_base::sync_with_stdio(false);
    cout.tie(0); cin.tie(0);

    cin >> n >> m;
    while(m--) {
        int a, b, t, c;
        cin >> a >> b >> t >> c;
        edg.push_back({ a, b, t, c });
    }

    point ans = { inf, inf };
    vector<pii> to_print;
    point byT = mst(1, 0), byC = mst(0, 1);
    
    if(byT < ans) ans = byT, to_print = used;
    if(byC < ans) ans = byC, to_print = used;

    stack<pair<point, point> > st;
    st.push({ byT, byC });

    while(!st.empty()) {
        auto [tl, br] = st.top(); st.pop();

        point nxt = mst(tl.y - br.y, br.x - tl.x);
        if(tl == nxt || br == nxt) continue;

        if(nxt < ans) {
            ans = nxt;
            to_print = used;
        }

        st.push({ tl, nxt });
        st.push({ nxt, br });
    }

    cout << ans.x << " " << ans.y << '\n';
    for(auto [a, b] : to_print)
        cout << a << " " << b << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...