标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8712 Accepted Submission(s): 3047
给你一棵树,每次询问两点间的距离。
跑一发离线lca,每次询问u,v,设c是u,v的lca,那么答案就是dis[u]+dis[v]-2*dis[c],其中dis表示从根到节点的距离。详见代码:
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<cstring> #include<cstdio> #include<vector> #define MAX_N 40003 using namespace std; bool vis[MAX_N]; struct edge { public: int to; long long cost; edge(int t, long long c) : to(t), cost(c) { } edge() { } }; vector<edge> G[MAX_N]; int q,n,m; struct node { public: int p, v; node(int pp, int vv) : p(pp), v(vv) { } node() { } }; vector<node> Q[MAX_N]; int lca[MAX_N], ancestor[MAX_N]; int T, cas = 0; int father[MAX_N]; void init() { for (int i = 0; i <= n; i++) father[i] = i; } int Find(int u) { if (u == father[u])return u; else return father[u] = Find(father[u]); } void unionSet(int u,int v) { int x = Find(u), y = Find(v); if (x == y)return; father[x] = y; } bool Same(int u,int v) { return Find(u) == Find(v); } long long dis[MAX_N]; void Tarjan(int u,int p) { for (int i = 0; i < G[u].size(); i++) { int v = G[u][i].to; if (v == p)continue; dis[v] = dis[u] + G[u][i].cost; Tarjan(v, u); unionSet(u, v); ancestor[Find(u)] = u; } vis[u] = 1; for (int i = 0; i < Q[u].size(); i++) { int v = Q[u][i].v; if (vis[v]) lca[Q[u][i].p] = ancestor[Find(v)]; } } pair<int, int> qu[MAX_N]; int main() { //cin.sync_with_stdio(false); scanf("%d", &T); while (T--) { scanf("%d%d", &n, &q); m = n - 1; init(); memset(vis, 0, sizeof(vis)); memset(ancestor, 0, sizeof(ancestor)); memset(dis, 0, sizeof(dis)); memset(lca, 0, sizeof(lca)); for (int i = 0; i <= n; i++)G[i].clear(); for (int i = 0; i <= n; i++)Q[i].clear(); for (int i = 0; i < m; i++) { int u, v; long long c; scanf("%d%d%I64d", &u, &v, &c); G[u].push_back(edge(v, c)); G[v].push_back(edge(u, c)); } for (int i = 0; i < q; i++) { int u, v; scanf("%d%d", &u, &v); qu[i] = make_pair(u, v); Q[u].push_back(node(i, v)); Q[v].push_back(node(i, u)); } Tarjan(1, 0); for (int i = 0; i < q; i++) printf("%I64d\n", dis[qu[i].first] + dis[qu[i].second] - 2 * dis[lca[i]]); } return 0; }
HDU 2586 How far away ? 离线lca模板题
标签:
原文地址:http://www.cnblogs.com/HarryGuo2012/p/4716763.html