結果
| 問題 |
No.901 K-ary εxtrεεmε
|
| コンテスト | |
| ユーザー |
goodbaton
|
| 提出日時 | 2019-10-05 01:39:36 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
RE
(最新)
AC
(最初)
|
| 実行時間 | - |
| コード長 | 4,075 bytes |
| コンパイル時間 | 1,354 ms |
| コンパイル使用メモリ | 123,780 KB |
| 実行使用メモリ | 42,164 KB |
| 最終ジャッジ日時 | 2024-10-04 06:29:47 |
| 合計ジャッジ時間 | 8,110 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 28 RE * 1 |
ソースコード
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <iostream>
#include <complex>
#include <string>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <functional>
#include <cassert>
#include <climits>
typedef long long ll;
using namespace std;
#ifndef LOCAL
#define debug(x) ;
#else
#define debug(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl;
template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
out << "{" << p.first << ", " << p.second << "}";
return out;
}
template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
out << '{';
for (const T &item : v) out << item << ", ";
out << "\b\b}";
return out;
}
#endif
#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010
/*Lowest Common Ancstor*/
struct LCA{
int n;
vector<vector<int>> tree, parent;
vector<int> depth;
int max_log;
LCA(int n): n(n), tree(n), depth(n, -1) {
max_log = 0;
for(int i=1; i<=n*2; i*=2) max_log++;
parent.assign(max_log, vector<int>(n, -1));
}
void add_edge(int u, int v) {
tree[u].push_back(v);
tree[v].push_back(u);
}
void dfs(int now, int p, int d){
parent[0][now] = p;
depth[now] = d;
for(int to : tree[now])
if(to != p)
dfs(to, now, d+1);
}
void build(int root){
dfs(root, -1, 0);
for(int i=0; i<max_log-1; i++)
for(int j=0; j<n; j++)
parent[i+1][j] = parent[i][j] == -1 ? -1 : parent[i][parent[i][j]];
}
int query(int a, int b){
if(depth[a] > depth[b]) swap(a, b);
for(int i=0; i<max_log; i++)
if((depth[b] - depth[a]) >> i & 1)
b = parent[i][b];
if(a == b) return a;
for(int i=max_log-1; i>=0; i--){
if(parent[i][a] != parent[i][b]){
a = parent[i][a];
b = parent[i][b];
}
}
return parent[0][a];
}
};
vector<pair<int,int>> G[SIZE];
ll dist[SIZE];
int parent[18][SIZE];
int eulerIn[SIZE], eulerOut[SIZE], counter = 0;
void dfs(int now, int back = -1, ll d = 0) {
assert(d <= INT_MAX);
dist[now] = d;
parent[0][now] = back;
eulerIn[now] = counter++;
for (auto p : G[now]) {
int to = p.first;
int cost = p.second;
if (to == back) continue;
dfs(to, now, d + cost);
}
eulerOut[now] = counter++;
}
int main(){
int N, Q;
scanf("%d", &N);
LCA lca(N);
for (int i=0; i<N-1; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[v].push_back({u, w});
G[u].push_back({v, w});
lca.add_edge(u, v);
}
lca.build(0);
dfs(0);
for (int i=0; i<18-1; i++) {
for (int j=0; j<N; j++) {
if (parent[i][j] == -1)
parent[i+1][j] = -1;
else
parent[i+1][j] = parent[i][parent[i][j]];
}
}
scanf("%d", &Q);
for (int i=0; i<Q; i++) {
int K;
scanf("%d", &K);
int g = -1;
set<int> ss;
priority_queue<pair<ll, int>> pq;
for (int j=0; j<K; j++) {
int x;
scanf("%d", &x);
if (j == 0) g = x;
else g = lca.query(g, x);
ss.insert(eulerIn[x]);
pq.push({dist[x], x});
}
ss.insert(eulerIn[g]);
ll ans = 0;
while (ss.size() > 1) {
auto p = pq.top();
pq.pop();
int x = p.second;
int tmp = x;
ss.erase(ss.find(eulerIn[x]));
for (int j=17; j>=0; j--) {
if (parent[j][tmp] == -1) continue;
int q = parent[j][tmp];
auto it = ss.lower_bound(eulerIn[q]);
if (it == ss.end() || eulerOut[q] < *it)
tmp = q;
}
auto it = ss.lower_bound(eulerIn[tmp]);
if (it == ss.end() || eulerOut[tmp] < *it)
tmp = parent[0][tmp];
ans += dist[x] - dist[tmp];
if (ss.find(eulerIn[tmp]) == ss.end()) {
pq.push({dist[tmp], tmp});
ss.insert(eulerIn[tmp]);
}
}
printf("%lld\n", ans);
}
return 0;
}
goodbaton