제출 #1271620

#제출 시각아이디문제언어결과실행 시간메모리
1271620VMaksimoski008통행료 (APIO13_toll)C++20
16 / 100
1 ms324 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 = 1e18;
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;
    }

    void clear() {
        for(int i=1; i<=n; i++) {
            par[i] = i;
            size[i] = 1;
        }
    }
};

ll sum[N], dp[N], par[N], par_w[N], dep[N];
int n, m, k, a[N], cmp[N], id=0;
vector<ar<int, 3> > e1;
vector<ar<int, 2> > e2;
vector<pii> g[N];

void dfs(int u, int c) {
    cmp[u] = c;
    sum[c] += a[u];
    for(auto [v, w] : g[u])
        if(!cmp[v]) dfs(v, c);
}

void dfs2(int u, int p) {
    dep[u] = dep[p] + 1;
    dp[u] = sum[u];
    par[u] = p;

    for(auto [v, w] : g[u]) if(v ^ p) {
        par_w[v] = w;
        dfs2(v, u);
        dp[u] += dp[v];
    }
}

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

    cin >> n >> m >> k;
    for(int i=0; i<m; i++) {
        int a, b, w;
        cin >> a >> b >> w;
        e1.push_back({ w, a, b });
    }

    for(int i=0; i<k; i++) {
        int a, b;
        cin >> a >> b;
        e2.push_back({ a, b });
    }

    for(int i=1; i<=n; i++) {
        cin >> a[i];
    }

    vector<ar<int, 3> > mst;
    sort(e1.begin(), e1.end());

    union_find dsu(n);
    for(auto [w, a, b] : e1) {
        if(dsu.uni(a, b)) {
            mst.push_back({ w, a, b });
        }
    }
    e1 = mst;
    m = e1.size();

    dsu.clear();
    for(auto [a, b] : e2)
        dsu.uni(a, b);

    vector<ar<int, 3> > bad;
    for(auto [w, a, b] : e1) {
        if(dsu.uni(a, b)) {
            g[a].push_back({ b, w });
            g[b].push_back({ a, w });
        } else {
            bad.push_back({ w, a, b });
        }
    }
    e1 = bad;

    for(int i=1; i<=n; i++) {
        if(cmp[i]) continue;
        dfs(i, ++id);
    }

    for(auto &[a, b] : e2) {
        a = cmp[a];
        b = cmp[b];
    }

    for(auto &[w, a, b] : e1) {
        a = cmp[a];
        b = cmp[b];
    }

    ll ans = 0;
    dsu.n = id;
    for(int mask=1; mask<(1<<k); mask++) {
        dsu.clear();
        for(int u=1; u<=id; u++)
            g[u].clear();

        bool ok = 1;
        for(int i=0; i<k; i++)
            if(mask & (1 << i))
                if(!dsu.uni(e2[i][0], e2[i][1]))
                    ok = 0;

        if(!ok) continue;

        for(int i=0; i<k; i++) {
            if(mask & (1 << i)) {
                g[e2[i][0]].push_back({ e2[i][1], 1 });
                g[e2[i][1]].push_back({ e2[i][0], 1 });
            }
        }

        vector<ar<int, 3> > bad2;
        for(auto [w, a, b] : e1) {
            if(dsu.uni(a, b)) {
                g[a].push_back({ b, 0 });
                g[b].push_back({ a, 0 });
            } else {
                bad2.push_back({ w, a, b });
            }
        }

        dfs2(1, 0);

        ll res = 0;
        vector<int> mn(id+1, 1e9);
        for(auto [w, a, b] : bad2) {
            if(dep[a] < dep[b]) swap(a, b);

            while(dep[a] > dep[b]) {
                mn[a] = min(mn[a], w);
                a = par[a];
            }

            while(a != b) {
                mn[a] = min(mn[a], w);
                mn[b] = min(mn[b], w);

                a = par[a];
                b = par[b];
            }
        }

        for(int i=1; i<=id; i++)
            ans += dp[i] * mn[i] * par_w[i];
        ans = max(ans, res);
    }

    cout << ans << '\n';
}
#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...