제출 #319331

#제출 시각아이디문제언어결과실행 시간메모리
319331marlicuPutovanje (COCI20_putovanje)C++14
110 / 110
160 ms26216 KiB
#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second

typedef pair <int, int> pii;

const int MAXN = 2e5 + 5;
const int LOG = 20;

int n, a, b, c1, c2;
vector <pii> veze[MAXN];
vector <pii> cijene;
int lca[LOG][MAXN];
int dubine[MAXN];
int koliko1[MAXN];
int koliko2[MAXN];
int zbroj[MAXN];

void dfs(int cvor, int roditelj, int dubina) {
    dubine[cvor] = dubina;

    for (auto ncvor : veze[cvor]) {
        if (ncvor.X == roditelj) continue;
        dfs(ncvor.X, cvor, dubina + 1);
        lca[0][ncvor.X] = cvor;
    }
}

int nadi_lca(int a, int b) {
    if (dubine[a] < dubine[b]) swap(a, b);

    for (int i = LOG; i >= 0; i--) {
        if (dubine[a] >= dubine[b] + (1 << i)) {
            a = lca[i][a];
        }
    }

    if (a == b) return a;

    for (int i = LOG - 1; i >= 0; i --) {
        if (lca[i][a] != lca[i][b]) {
            a = lca[i][a];
            b = lca[i][b];
        }
    }

    return lca[0][a];
}

void rek(int cvor, int roditelj, int cesta) {
    for (auto ncvor : veze[cvor]) {
        if (ncvor.X == roditelj) continue;
        rek(ncvor.X, cvor, ncvor.Y);
        zbroj[cvor] += zbroj[ncvor.X];
    }

    zbroj[cvor] += koliko1[cvor];

    if (cesta != -1) koliko2[cesta] = zbroj[cvor];
}

void ispis() {
    for (int i = 1; i <= n; i++) {
        cout << i << " : ";
        for (auto nx : veze[i]) cout << nx.X << " ";
        cout << '\n';
    }
    cout << '\n';

    for (int i = 1; i <= n; i++) cout << dubine[i] << " ";
    cout << '\n'; cout << '\n';

    for (int i = 0; i < 4; i++) {
        for (int j = 1; j <= n; j++) {
            cout << lca[i][j] << " ";
        }
        cout << '\n';
    }
    cout << '\n';
}

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

    cin >> n;
    for (int i = 0; i < n - 1; i++) {
        cin >> a >> b >> c1 >> c2;
        veze[a].push_back({b, i});
        veze[b].push_back({a, i});
        cijene.push_back({c1, c2});
    }

    dfs(1, -1, 0);

    //ispis();

    for (int i = 1; i < LOG; i++) {
        for (int j = 1; j <= n; j++) {
            lca[i][j] = lca[i - 1][lca[i - 1][j]];
        }
    }

    //ispis();

    for (int i = 1; i < n; i++) {
        int zajednicki = nadi_lca(i, i + 1);
        koliko1[i]++;
        koliko1[i + 1]++;
        koliko1[zajednicki] -= 2;
    }

    rek(1, -1, -1);

    long long ukupno = 0;
    for (int i = 0; i < n - 1; i++) {
        ukupno += min((long long)koliko2[i] * cijene[i].X, (long long)cijene[i].Y);
    }
    cout << ukupno << '\n';

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