이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |