이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <iostream>
#include <vector>
#include <array>
#include <map>
using namespace std;
using ll = long long;
using pii = array<int, 2>;
const int maxn = 200'001;
const int LOG = 19;
int n;
vector<int> tree[maxn];
int used[maxn],
seen[maxn],
depth[maxn],
ancestor[LOG][maxn];
pii cost[maxn];
map<pii, int> ident;
void dfs(int u, int p, int d){
ancestor[0][u] = p;
depth[u] = d;
for(int & v : tree[u])
if(v != p)
dfs(v, u, d + 1);
}
void calculateFrequencyOfEdge(int u, int p){
for(int & v : tree[u])
if(v != p){
calculateFrequencyOfEdge(v, u);
seen[u] += seen[v];
}
if(u != p)
used[ident[{min(u, p), max(u, p)}]] += seen[u];
}
int main(){
cin.tie(nullptr)->sync_with_stdio(false);
cin >> n;
for(int i = 0; i < (n - 1); i++){
int a, b, c1, c2;
cin >> a >> b >> c1 >> c2;
tree[a].emplace_back(b);
tree[b].emplace_back(a);
cost[i] = {c1, c2};
ident[{min(a, b), max(a, b)}] = i;
}
dfs(1, 1, 0);
for(int i = 1; i < LOG; i++)
for(int u = 1; u <= n; u++)
ancestor[i][u] = ancestor[i - 1][ancestor[i - 1][u]];
for(int a = 1; a <= (n - 1); a++){
int b = (a + 1);
int _a = a, _b = b;
if(depth[_b] > depth[_a])
swap(_a, _b);
int dif = depth[_a] - depth[_b];
for(int i = LOG - 1; i >= 0; i--)
if((1 << i) & dif)
_a = ancestor[i][_a];
if(_b == _a){
if(depth[b] > depth[a]){
++seen[b];
--seen[a];
} else {
++seen[a];
--seen[b];
}
} else {
for(int i = LOG - 1; i >= 0; i--)
if(ancestor[i][_a] != ancestor[i][_b])
_a = ancestor[i][_a],
_b = ancestor[i][_b];
_a = ancestor[0][_a];
++seen[a];
++seen[b];
seen[_a] -= 2;
}
}
calculateFrequencyOfEdge(1, 1);
ll answer = 0;
for(int i = 0; i < (n - 1); i++){
answer += min((ll) cost[i][1], (ll) used[i]*cost[i][0]);
}
cout << answer << '\n';
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |