#include <bits/stdc++.h>
using namespace std;
struct Edge {
int u, v;
int c1, c2;
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<Edge> edges(N-1);
vector<vector<pair<int,int>>> adj(N+1); // adj[node] = vector of (neighbor, edge index)
for(int i=0; i < N-1; i++){
int A, B, C1, C2;
cin >> A >> B >> C1 >> C2;
edges[i] = {A, B, C1, C2};
adj[A].push_back({B, i});
adj[B].push_back({A, i});
}
// Root the tree at node 1. We'll use BFS to compute parent and depth.
vector<int> par(N+1, 0), depth(N+1, 0), parentEdge(N+1, -1);
vector<bool> visited(N+1, false);
queue<int> q;
visited[1] = true;
par[1] = 0;
depth[1] = 0;
q.push(1);
while(!q.empty()){
int u = q.front();
q.pop();
for(auto &pr : adj[u]){
int v = pr.first, eidx = pr.second;
if(!visited[v]){
visited[v] = true;
par[v] = u;
depth[v] = depth[u] + 1;
parentEdge[v] = eidx;
q.push(v);
}
}
}
// Build binary lifting table for LCA.
int LOG = 0;
while((1 << LOG) <= N) LOG++;
vector<vector<int>> up(N+1, vector<int>(LOG,0));
for (int i=1; i<=N; i++){
up[i][0] = par[i];
}
for (int j=1; j<LOG; j++){
for (int i=1; i<=N; i++){
int mid = up[i][j-1];
up[i][j] = (mid == 0 ? 0 : up[mid][j-1]);
}
}
auto lca = [&](int u, int v) -> int {
if(depth[u] < depth[v]) swap(u, v);
int diff = depth[u] - depth[v];
for (int j = 0; diff; j++){
if(diff & 1)
u = up[u][j];
diff >>= 1;
}
if(u == v)
return u;
for (int j = LOG-1; j >= 0; j--){
if(up[u][j] != up[v][j]){
u = up[u][j];
v = up[v][j];
}
}
return par[u];
};
// Frequency array: for each journey from town i to i+1, add +1 at endpoints and -2 at LCA.
vector<long long> freq(N+1, 0);
for(int i = 1; i < N; i++){
int u = i, v = i+1;
int w = lca(u, v);
freq[u]++;
freq[v]++;
freq[w] -= 2;
}
// Process nodes in order of descending depth (so that every child is processed before its parent)
vector<int> order(N);
for (int i = 0; i < N; i++){
order[i] = i+1;
}
sort(order.begin(), order.end(), [&](int a, int b){
return depth[a] > depth[b];
});
long long ans = 0;
for(auto node : order){
if(node == 1) continue; // Skip the root (no parent edge)
int e = parentEdge[node];
long long useCount = freq[node];
long long costSingle = useCount * 1LL * edges[e].c1;
long long costMulti = edges[e].c2;
ans += min(costSingle, costMulti);
freq[par[node]] += freq[node]; // Propagate the frequency upward.
}
cout << ans << "\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... |