您的位置:首页 > 其它

ZOJ 3195(LCA模板)

2016-05-01 16:25 337 查看
题意:给一个带权图 然后q个询问 每个询问有三个数x y z,求x y z这三个点连接起来需要多少距离。

LCA 对于每个询问求出任意两个点对的LCA 加和 / 2。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
using namespace std;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
const int maxn = 50000 + 7;
const int INF = ~0U >> 1;

struct node { int v, val; };
struct ask  { int u, v, lca; };

vector<node> G[maxn];
vector<ask> e;
vector<int> query[maxn];
int p[maxn], ans[maxn], d[maxn], vis[maxn];
int n, q;

int Find(int x) {
return p[x] == x ? x : p[x] = Find(p[x]);
}

void addEdge(int u, int v, int val) {
G[u].push_back((node) {v, val});
G[v].push_back((node) {u, val});
}

void addAsk(int u, int v) {
e.push_back((ask) {u, v, -1});
e.push_back((ask) {v, u, -1});
int len = e.size() - 1;
query[u].push_back(len - 1);
query[v].push_back(len);
}

void init() {
for(int i = 0; i < n; ++i) p[i] = i, G[i].clear(), query[i].clear();
memset(d, 0, sizeof(d));
memset(vis, 0, sizeof(vis));
memset(ans, 0, sizeof(ans));
e.clear();
}

void Tarjan(int u, int val) {
vis[u] = 1;
ans[u] = u;
d[u] = val;
for(int i = 0; i < G[u].size(); ++i) {
node& to = G[u][i];
if(!vis[to.v]) {
Tarjan(to.v, val + to.val);
int x = Find(u), y = Find(to.v);
if(x != y) p[to.v] = u;
}
}
for(int i = 0; i < query[u].size(); ++i) {
int w = query[u][i];
ask& temp = e[w];
if(vis[temp.v]) temp.lca = e[w^1].lca = ans[Find(temp.v)];
}
}
int main() {
int u, v, val;
int kase = 0;
while(scanf("%d", &n) != EOF) {
init();
for(int i = 0; i < n - 1; ++i) {
scanf("%d%d%d", &u, &v, &val);
addEdge(u, v, val);
}
scanf("%d", &q);
int x, y, z;
for(int i = 0; i < q; ++i) {
scanf("%d%d%d", &x, &y, &z);
addAsk(x, y);
addAsk(x, z);
addAsk(y, z);
}
if(kase) puts("");
kase++;
Tarjan(0, 0);
int ans = 0;
for(int i = 0; i < 3 * q; ++i) {
ans += (d[e[i*2].u] + d[e[i*2].v] - 2 * d[e[i*2].lca]);
if(i % 3 == 2) {
printf("%d\n", ans / 2);
ans = 0;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: