比赛 |
ZLXOI2015Day2 |
评测结果 |
AAAAAAAAAA |
题目名称 |
ZLX的陨落 |
最终得分 |
100 |
用户昵称 |
Skyo |
运行时间 |
0.768 s |
代码语言 |
C++ |
内存使用 |
41.49 MiB |
提交时间 |
2015-10-30 19:32:25 |
显示代码纯文本
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long L;
int n, m, q, d[100005]; L F[100005][25], D[100005][25];
int h[100005], nx[200005], v[200005], w[200005];
void Initialize()
{
freopen("ThefallingofZLX.in", "r", stdin);
freopen("ThefallingofZLX.out", "w", stdout);
scanf("%d %d", &n, &m);
for(int i = 1; i <= m; i++)
{
int ui, vi, wi; scanf("%d %d %d", &ui, &vi, &wi);
int e1 = i*2-1, e2 = i*2;
nx[e1] = h[ui], h[ui] = e1, v[e1] = vi, w[e1] = wi;
nx[e2] = h[vi], h[vi] = e2, v[e2] = ui, w[e2] = wi;
}
scanf("%d", &q);
}
void DFS(int u, int fa)
{
F[u][0] = fa;
d[u] = d[fa] + 1;
for(int i = 1; (1<<i) <= d[u]; i++)
{
F[u][i] = F[F[u][i-1]][i-1];
D[u][i] = D[F[u][i-1]][i-1] + D[u][i-1];
}
for(int i = h[u]; i; i = nx[i]) if(v[i] != fa)
{
D[v[i]][0] = w[i];
DFS(v[i], u);
}
}
L LCA(int a, int b)
{
L res = 0;
if(d[a] < d[b]) swap(a, b);
while(d[a] != d[b])
{
int k = 2+(int)(log(d[a]-d[b])/log(2.0));
while(d[F[a][k]] < d[b] && k) k--;
res += D[a][k]; a = F[a][k];
}
if(a == b) return res;
while(a != b)
{
int k = 18;
while(F[a][k] == F[b][k] && k) k--;
res += D[a][k] + D[b][k];
a = F[a][k], b = F[b][k];
}
return res;
}
int main()
{
Initialize();
DFS(1, 0);
while(q--)
{
int ui, vi; scanf("%d %d", &ui, &vi);
printf("%lld\n", LCA(ui, vi));
}
return 0;
}