Submission #1271593

#TimeUsernameProblemLanguageResultExecution timeMemory
1271593VMaksimoski008Toll (APIO13_toll)C++20
16 / 100
3 ms328 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;
    }
};

ll ans = 0, sub[N], dp[N];
int n, m, k, a[N], up[N][20], mx[N][20], dep[N];
vector<pii> g[N];
vector<ar<int, 3> > e1, e2;
vector<ar<int, 3> > T[N];

bool cmp(ar<int, 4> x, ar<int, 4> y) {
    if(x[0] != y[0]) return x[0] < y[0];
    return x[1] < y[1];
}

void dfs(int u, int p) {
    dep[u] = dep[p] + 1;
    for(int i=1; i<20; i++) {
        up[u][i] = up[up[u][i-1]][i-1];
        mx[u][i] = max(mx[u][i-1], mx[up[u][i-1]][i-1]);
    }

    for(auto [v, w] : g[u]) if(v ^ p) {
        up[v][0] = u;
        mx[v][0] = w;
        dfs(v, u);
    }
}

pii lca(int a, int b) {
    if(dep[a] < dep[b]) swap(a, b);
    int d = dep[a] - dep[b], ans = 0;

    for(int i=19; i>=0; i--) {
        if(d & (1 << i)) {
            ans = max(ans, mx[a][i]);
            a = up[a][i];
        }
    }

    if(a == b) return { a, ans };

    for(int i=19; i>=0; i--) {
        if(up[a][i] != up[b][i]) {
            ans = max(ans, mx[a][i]);
            ans = max(ans, mx[b][i]);

            a = up[a][i];
            b = up[b][i];
        }
    }

    return { up[a][0], max(ans, mx[a][0]) };
}

void build_mst() {
    union_find dsu(n);
    sort(e1.begin(), e1.end());

    for(auto [w, a, b] : e1) {
        if(dsu.uni(a, b)) {
            g[a].push_back({ b, w });
            g[b].push_back({ a, w });
        }
    }

    dfs(1, 0);
}

int calc(int u, int p) {
    dp[u] = 0;
    sub[u] = a[u];

    for(auto [v, w, t] : T[u]) if(v ^ p) {
        sub[u] += calc(v, u);
        dp[u] += dp[v];
        if(!t) dp[u] += (ll)w * sub[v];
    }

    return sub[u];
}

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

    cin >> n >> m >> k;

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

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

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

    build_mst();
    for(int mask=1; mask<(1<<k); mask++) {
        for(int u=1; u<=n; u++) T[u].clear();
        vector<ar<int, 4> > ord;

        for(int i=0; i<m; i++) {
            ord.push_back({ e1[i][0], 1, e1[i][1], e1[i][2] });
        }

        for(int i=0; i<k; i++) {
            if(mask & (1 << i)) {
                int mx = lca(e2[i][1], e2[i][2]).second;
                ord.push_back({ mx, 0, e2[i][1], e2[i][2] });
            }
        }

        union_find dsu(n);
        sort(ord.begin(), ord.end(), cmp);

        for(auto [w, t, a, b] : ord) {
            if(dsu.uni(a, b)) {
                T[a].push_back({ b, w, t });
                T[b].push_back({ a, w, t });
            }
        }

        calc(1, 0);
        ans = max(ans, dp[1]);
    }
    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...