제출 #311694

#제출 시각아이디문제언어결과실행 시간메모리
311694thecodingwizardPutovanje (COCI20_putovanje)C++11
110 / 110
221 ms23288 KiB
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
#define ii pair<int, int>
#define f first
#define s second
#define mp make_pair
#define pb push_back

int n; 
vector<pair<int, ii>> adj[200000];
int pa[200000][20];
int depth[200000];
int in[200000], out[200000], ctr = 0;

void dfs(int u, int p, int d) {
    in[u] = ctr++;
    pa[u][0] = p;
    depth[u] = d;
    for (auto v : adj[u]) {
        if (v.f != p) dfs(v.f, u, d+1);
    }
    out[u] = ctr-1;
}

int lca(int a, int b) {
    if (depth[a] < depth[b]) swap(a, b);
    for (int i = 19; i >= 0; i--) {
        if (depth[pa[a][i]] >= depth[b]) a = pa[a][i];
    }
    if (a == b) return a;
    for (int i = 19; i >= 0; i--) {
        if (pa[a][i] != pa[b][i]) {
            a = pa[a][i], b = pa[b][i];
        }
    }
    return pa[a][0];
}

int ft[200001];
void upd(int k, int v) {
    k++;
    while (k <= 200000) {
        ft[k] += v;
        k += k&-k;
    }
}
int qry(int k) {
    k++;
    int ans = 0;
    while(k) {
        ans += ft[k];
        k -= k&-k;
    }
    return ans;
}

ll ans = 0;
void dfs2(int u, int p) {
    for (auto v : adj[u]) {
        if (v.f == p) continue;
        assert(depth[v.f] = depth[u]+1);
        ll numTraversals = qry(out[v.f]) - qry(in[v.f]-1);
        //cout << u << "->" << v.f << ": " << min(numTraversals*v.s.f, (ll)v.s.s) << endl;
        ans += min(numTraversals*v.s.f, (ll)v.s.s);
        dfs2(v.f, u);
    }
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin >> n;

    for (int i = 0; i < n-1; i++) {
        int a, b, c, d; cin >> a >> b >> c >> d; --a; --b;
        adj[a].push_back(mp(b, mp(c, d)));
        adj[b].push_back(mp(a, mp(c, d)));
    }

    dfs(0, 0, 0);

    for (int j = 1; j < 20; j++) {
        for (int i = 0; i < n; i++) {
            pa[i][j] = pa[pa[i][j-1]][j-1];
        }
    }

    for (int i = 0; i < n-1; i++) {
        int x = lca(i, i+1);
        assert(depth[i] >= depth[x]);
        assert(depth[i+1] >= depth[x]);
        upd(in[i], 1);
        upd(in[i+1], 1);
        upd(in[x], -2);
    }

    dfs2(0, 0);
    cout << ans << endl;

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...