HDU 2586 How far away ?(lca)
来源:互联网 发布:cf卡数据恢复 mac 编辑:程序博客网 时间:2024/06/05 08:25
Problem Description
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 3
2 2
1 2 100
1 2
2 1
Sample Output
10
25
100
100
大致题意:个村子里有n个房子,这n个房子用n-1条双向道路连接起来,接下了有m次询问,每次询问两个房子a,b之间的距离是多少。
思路:lca模板题
代码如下
模板一:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm>using namespace std; const int N = 40010; const int M = 25; int dp[2*N][M]; //这个数组记得开到2*N,因为遍历后序列长度为2*n-1 bool vis[N]; struct edge { int v,w,next; }e[2*N]; //链式向前星存边int tot,head[N]; int tol; inline void add(int u ,int v ,int w ) { e[tol].v = v; e[tol].w = w; e[tol].next = head[u]; head[u] = tol++; u = u^v; v = u^v; u = u^v; e[tol].v = v; e[tol].w = w; e[tol].next = head[u]; head[u] = tol++; } int ver[2*N],R[2*N],first[N],dir[N]; //ver:节点编号 R:深度 first:点编号位置 dir:距离 void dfs(int u ,int dep) { vis[u] = true; ver[++tot] = u; first[u] = tot; R[tot] = dep; for(int k=head[u]; k!=-1; k=e[k].next) if( !vis[e[k].v] ) { int v = e[k].v , w = e[k].w; dir[v] = dir[u] + w; dfs(v,dep+1); ver[++tot] = u; R[tot] = dep; } } void ST(int n) { for(int i=1;i<=n;i++) dp[i][0] = i; for(int j=1;(1<<j)<=n;j++) { for(int i=1;i+(1<<j)-1<=n;i++) { int a = dp[i][j-1] , b = dp[i+(1<<(j-1))][j-1]; dp[i][j] = R[a]<R[b]?a:b; } } } //中间部分是交叉的。 int RMQ(int l,int r) { int k=0; while((1<<(k+1))<=r-l+1) k++; int a = dp[l][k], b = dp[r-(1<<k)+1][k]; //保存的是编号 return R[a]<R[b]?a:b; } int LCA(int u ,int v) { int x = first[u] , y = first[v]; if(x > y) swap(x,y); int res = RMQ(x,y); return ver[res]; } int main() { int cas; scanf("%d",&cas); while(cas--) { int n,q; tol=0; scanf("%d%d",&n,&q); memset(head,-1,sizeof(head)); memset(vis,false,sizeof(vis)); for(int i=1; i<n; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } tot = 0; dir[1] = 0; dfs(1,1); ST(2*n-1); while(q--) { int u,v; scanf("%d%d",&u,&v); int lca = LCA(u,v); printf("%d\n",dir[u] + dir[v] - 2*dir[lca]); } } return 0; }
模板二:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <vector> using namespace std; const int N=40005;const int M=40005;int head[N];int dis[N];int deep[N],fa[N],pre[N];int n,m,q,tol;bool vis[N];struct Edge//链式向前星存边 { int to,cost; int next;}edge[M*2];void addedge(int u,int v,int cost){ edge[tol].to=v; edge[tol].cost=cost; edge[tol].next=head[u]; head[u]=tol++;}void dfs(int s){ vis[s]=1; for(int i=head[s];i!=-1;i=edge[i].next) { int to=edge[i].to; if(!vis[to]) { fa[to]=s; deep[to]=deep[s]+1; dis[to]=dis[s]+edge[i].cost; dfs(to); } }}int lca(int x,int y){ if(deep[x]>deep[y]) swap(x,y); while(deep[x]!=deep[y]) { y=fa[y]; } while(x!=y) { x=fa[x]; y=fa[y]; //cout<<x<<' '<<y<<endl; } return x;}void init(){ memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { pre[i]=i; dis[i]=0; } tol=0;}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); init(); int u,v,cost; for(int i=1;i<=n-1;i++) { scanf("%d%d%d",&u,&v,&cost); addedge(u,v,cost); addedge(v,u,cost); } dfs(1);//建树 for(int i=1;i<=q;i++) { int u,v; scanf("%d%d",&u,&v); printf("%d\n",dis[u]+dis[v]-dis[lca(u,v)]*2); } } return 0;}
- HDU 2586 - How far away ? (LCA)
- hdu 2586 How far away ?(LCA)
- HDU 2586 How far away ?(LCA)
- hdu 2586 How far away ?(LCA)
- How far away ? (hdu 2586 LCA)
- hdu 2586 How far away ?(LCA)
- HDU 2586 How far away ?(LCA)
- HDU 2586How far away ?(LCA)
- hdu-2586 How far away ?(LCA)
- HDU 2586 How far away ?(LCA)
- HDU 2586 How far away ?(lca)
- HDU 2586 How far away? LCA模板
- HDU--2586--How far away ?【LCA】
- hdu 2586 How far away ?(LCA)
- HDU - 2586 How far away ?(LCA)
- HDU---2586-How far away(LCA)
- HDU 2586 How far away ?【LCA】
- HDU 2586 How far away ?(lca)
- Ultra-QuickSort
- C#中数组、ArrayList和List三者的区别
- 北大 AI 公开课第11讲:微软副总裁洪小文——AI+HI是终极智能形态
- 解决Android反编译XML文件乱码问题
- Android技术痛点——各种键盘挡住输入框终极解决办法
- HDU 2586 How far away ?(lca)
- 数据结构OJ作业——最短路、拓扑排序
- 用户用浏览器访问一个网站的时候背后的过程与步骤是怎样的?
- Intent使用详解
- Eclipse构建项目时"An internal error occurred during: "Building workspace". Java heap space"
- 机器学习知识点(三十)LDA话题模型Java实现
- 将项目发布到 maven 中央仓库踩过的坑
- java中拼音和中文互相转换
- 【mysql】根据不同条件查询表中同一字段