*【HDU - 2586】How far away ? (LCA模板题,倍增)
題干:
There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.
Input
First line is a single integer T(T<=10), indicating the number of test cases.?
??For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.?
??Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
2 3 2 1 2 10 3 1 15 1 2 2 32 2 1 2 100 1 2 2 1Sample Output
10 25 100 100解題報告:
? ?沒想到ccf的時候剛學的lca,,第二周實驗室的題就用到了2333。。Tarjan的方法也學了一些抽空寫了。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 5e4 + 5; bool vis[MAX]; int dep[MAX],fa[MAX][33],cost[MAX][33];int n,m; vector<int> vv[MAX]; vector<int> ww[MAX]; //int f[MAX][30],fa[MAX]; //void dfs(int cur) { // vis[cur] = 1; // int up = vv[cur].size(); // for(int i = 0; i<up; i++) { // int v = vv[cur][i]; // if(vis[v]) continue; // fa[v] = cur; // dep[v] = dep[cur]+1; // dfs(v); // } //} //void bz() { // for(int i = 1; i<=n; i++) f[i][0] = fa[i]; // for(int j = 1; j<=30; j++) { // for(int i = 1; i<=n; i++) { // f[i][j] = f[f[i][j-1]][j-1]; // } // } //} void dfs(int cur, int rt) {fa[cur][0] = rt;dep[cur] = dep[rt] + 1;for(int i = 1; i < 31; ++i) {fa[cur][i] = fa[fa[cur][i - 1]][i - 1];cost[cur][i] = cost[fa[cur][i - 1]][i - 1] + cost[cur][i - 1];}int sz = vv[cur].size();for (int i = 0; i < sz; ++i) {if (vv[cur][i] == rt) continue;cost[vv[cur][i]][0] = ww[cur][i];dfs(vv[cur][i], cur);} } int lca(int u,int v) {if(dep[u] < dep[v]) swap(u,v);int res = 0;int dc = dep[u]-dep[v];for(int i = 0; i<=30; i++) {if((1<<i) & dc) res += cost[u][i],u=fa[u][i];} // for (int j = 0; dc; ++j, dc >>= 1) // if (dc & 1) res += cost[u][j], u = fa[u][j];if(u == v) return res;for(int i = 30; i>=0 && u!=v; i--) {if(fa[u][i] != fa[v][i]) {res += cost[v][i] + cost[u][i]; u=fa[u][i];v=fa[v][i];}}res += cost[u][0] + cost[v][0]; u=fa[u][0];return res; }//int lca(int x, int y) { // if (dep[x] > dep[y]) swap(x, y); // int tmp = dep[y] - dep[x], ans = 0; // for (int j = 0; tmp; ++j, tmp >>= 1) // if (tmp & 1) ans += cost[y][j], y = fa[y][j]; // if (y == x) return ans; // for (int j = 30; j >= 0 && y != x; --j) { // if (fa[x][j] != fa[y][j]) { // ans += cost[x][j] + cost[y][j]; // x = fa[x][j]; // y = fa[y][j]; // } // } // ans += cost[x][0] + cost[y][0]; // return ans; //} int main() {int t;cin>>t;while(t--) {scanf("%d%d",&n,&m);for(int i = 1; i<=n; i++) vv[i].clear(),ww[i].clear();for(int a,b,c,i = 1; i<=n-1; i++) {scanf("%d%d%d",&a,&b,&c);vv[a].pb(b);vv[b].pb(a);ww[a].pb(c);ww[b].pb(c);}dfs(1,-1);while(m--) {int a,b;scanf("%d%d",&a,&b);printf("%d\n",lca(a,b));}}return 0 ;}?
總結
以上是生活随笔為你收集整理的*【HDU - 2586】How far away ? (LCA模板题,倍增)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【POJ - 3020】Antenna
- 下一篇: 【牛客 - 315C】排列(思维,贪心,