結果
| 問題 |
No.898 tri-βutree
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-10-05 02:22:53 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 486 ms / 4,000 ms |
| コード長 | 2,407 bytes |
| コンパイル時間 | 1,170 ms |
| コンパイル使用メモリ | 91,972 KB |
| 実行使用メモリ | 35,712 KB |
| 最終ジャッジ日時 | 2024-11-08 22:45:22 |
| 合計ジャッジ時間 | 10,137 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 21 |
ソースコード
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
using namespace std;
#define MOD 1000000007
#define INF (1 << 29)
#define LINF (1LL << 60)
#define EPS (1e-10)
typedef long long Int;
typedef pair<Int, Int> P;
Int ppp;
Int come[110000];
Int p[110000][20];
Int depth[110000];
Int node[110000];
Int weight[110000];
vector<P> edge[110000];
void dfs(Int x, Int last = -1, Int d = 0)
{
come[x] = ppp;
node[ppp] = x;
depth[x] = d;
ppp++;
if (last != -1)
{
for (Int i = 0; i < 20; i++)
{
if (i == 0)
p[x][i] = last;
else
p[x][i] = p[p[x][i - 1]][i - 1];
}
}
for (auto p : edge[x])
{
Int to = p.first, w = p.second;
if (to == last)
continue;
weight[to] = weight[x] + w;
dfs(to, x, d + 1);
}
}
Int la(Int x, Int d, Int pp = 19)
{
if (d == 0)
return x;
while (d < (1 << pp))
pp--;
x = p[x][pp];
return la(x, d - (1 << pp), pp);
}
Int lca(Int x, Int y)
{
if (depth[x] < depth[y])
swap(x, y);
if (depth[x] > depth[y])
x = la(x, depth[x] - depth[y]);
if (x == y)
return x;
if (depth[x] != depth[y])
exit(1);
Int up = 19;
while (p[x][0] != p[y][0])
{
while (p[x][up] == p[y][up])
up--;
x = p[x][up];
y = p[y][up];
}
return p[x][0];
}
void solve()
{
Int k=3, ans = 0;
vector<Int> nodes;
for (Int i = 0; i < k; i++)
{
Int x;
cin >> x;
nodes.push_back(come[x]);
}
sort(nodes.begin(), nodes.end());
for (Int i = 0; i < k; i++)
{
Int x = node[nodes[i]];
Int y = node[nodes[(i + 1) % k]];
Int l = lca(x, y);
//cout << x << ":" << weight[x] << " " << y << ":" << weight[y] << " " << l << ":" << weight[l] << endl;
ans += weight[x] - weight[l];
ans += weight[y] - weight[l];
}
cout << ans / 2 << endl;
}
int main()
{
int n, u, v, w, q;
cin >> n;
for (Int i = 0; i < n - 1; i++)
{
cin >> u >> v >> w;
edge[u].push_back(P(v, w));
edge[v].push_back(P(u, w));
}
dfs(0);
cin >> q;
while (q--)
solve();
return 0;
}