結果
| 問題 |
No.386 貪欲な領主
|
| コンテスト | |
| ユーザー |
笹暮339
|
| 提出日時 | 2023-09-30 01:31:03 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 362 ms / 2,000 ms |
| コード長 | 2,949 bytes |
| コンパイル時間 | 2,041 ms |
| コンパイル使用メモリ | 182,036 KB |
| 実行使用メモリ | 16,820 KB |
| 最終ジャッジ日時 | 2024-07-22 19:27:53 |
| 合計ジャッジ時間 | 5,157 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 16 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using Graph1 = vector<vector<int>>;
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define all(x) (x).begin(),(x).end()
const ll INF = 1LL<<60;
// LCA(最近共通祖先)
struct LCA{
vector<vector<int>> parent;
vector<int> dist;
LCA(const Graph1 &g, int root ) { init(g,root);}
void init(const Graph1 &g,int root){
int V = g.size();
int K = 1;
while((1<<K)<V) K++;
parent.assign(K,vector<int>(V,-1));
dist.assign(V,-1);
bfs(g,root);
for(int k=0;k+1<K;k++){
for(int v=0;v<V;v++){
if(parent[k][v]<0){
parent[k+1][v] = -1;
}
else{
parent[k+1][v] = parent[k][parent[k][v]];
}
}
}
}
void bfs(const Graph1 &g,int v){
int N = (int)g.size();
queue<int> todo;
parent[0][v] = -1;
dist[v] = 0;
todo.push(v);
while(!todo.empty()){
int pos = todo.front();
todo.pop();
for(int x:g[pos]){
if(dist[x]!=-1) continue;
parent[0][x] = pos;
dist[x] = dist[pos]+1;
todo.push(x);
}
}
}
int query(int u,int v){
if(dist[u]<dist[v]) swap(u,v);
int K = parent.size();
for(int k = 0;k<K;k++){
if((dist[u]-dist[v]) >> k&1){
u = parent[k][u];
}
}
if(u==v) return u;
for(int k=K-1;k>=0;k--){
if(parent[k][u]!=parent[k][v]){
u = parent[k][u];
v = parent[k][v];
}
}
return parent[0][u];
}
int get_dist(int u,int v){
return dist[u]+dist[v]-2*dist[query(u,v)];
}
bool is_on_path(int u,int v,int a){
return get_dist(u,a)+get_dist(a,v) == get_dist(u,v);
}
};
int main(){
int n;
cin >> n;
Graph1 gr(n);
rep(i,n-1){
int a,b;
cin >> a >> b;
gr[a].push_back(b);
gr[b].push_back(a);
}
LCA lca = LCA(gr,0);
vector<int> seen(n,-1);
vector<int> one(n);
rep(i,n){
int u;
cin >> u;
seen[i] = u;
one[i] = u;
}
queue<int> que;
que.push(0);
vector<bool> visi(n,false);
visi[0] = true;
while(!que.empty()){
int pos = que.front();
que.pop();
for(auto nex:gr[pos]){
if(visi[nex]) continue;
visi[nex] = true;
seen[nex]+=seen[pos];
que.push(nex);
}
}
int m;
cin >> m;
ll ren = 0;
rep(i,m){
int a,b,c;
cin >> a >> b >> c;
ll ans = seen[a]+seen[b]-2*seen[lca.query(a,b)]+one[lca.query(a,b)];
ren += ans*c;
}
cout <<ren<<endl;
}
笹暮339