ZOJ 3195 LCA

来源:互联网 发布:德国联邦网络局 编辑:程序博客网 时间:2024/05/21 17:32
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>using namespace std;const int maxn = 2E5 + 10;int n, m, x, y, z, kase;struct Node{int to, val;Node(int to = 0, int val = 0): to(to), val(val) {}};struct Ask{int u, v, lca;Ask(int u = 0, int v = 0, int lca = 0): u(u), v(v), lca(lca) {}};vector<Ask>e;vector<Node>g[maxn];vector<int>query[maxn];bool vis[maxn];int fa[maxn], ance[maxn], dir[maxn];void init(){memset(vis, 0, sizeof(vis));for (int i = 0; i <= n; i++)g[i].clear(), query[i].clear();e.clear();}void Add_Node(){int u, v, w;scanf("%d%d%d", &u, &v, &w);g[u].push_back(Node(v, w));g[v].push_back(Node(u, w));}void Add_Ask(int u, int v){e.push_back(Ask(u, v, -1));e.push_back(Ask(v, u, -1));int len = e.size() - 1;query[v].push_back(len);query[u].push_back(len - 1);}void Add_Ask(){scanf("%d%d%d", &x, &y, &z);Add_Ask(x, y); Add_Ask(x, z); Add_Ask(y, z);}int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}void Tarjan(int u, int val){vis[u] = true;ance[u] = fa[u] = u;dir[u] = val;for (int i = 0; i < g[u].size(); i++)if (!vis[g[u][i].to]){Node tmp = g[u][i];Tarjan(tmp.to, val + tmp.val);fa[tmp.to] = u;}for (int i = 0; i < query[u].size(); i++){int num = query[u][i];Ask& tmp  = e[num];if (vis[tmp.v])tmp.lca = e[num ^ 1].lca = ance[Find(tmp.v)];}}int main(int argc, char const *argv[]){while (~scanf("%d", &n)){init();for (int i = 1; i < n; i++)Add_Node();scanf("%d", &m);for (int i = 0; i < m; i++)Add_Ask();Tarjan(0, 0);if (kase++) printf("\n");int ans = 0;for (int i = 0; i < 3 * m; i++){ans += (dir[e[i * 2].u] + dir[e[i * 2].v] - 2 * dir[e[i * 2].lca]);if (i % 3 == 2) printf("%d\n", ans / 2), ans = 0;}}return 0;}


给出一个图,求三点的连起来的距离。

Tarjan离线算法,分别求出三点中任意两点的距离 / 2 

0 0
原创粉丝点击