Hdu 2586 How far away ?【lca】

来源:互联网 发布:java开发转行 编辑:程序博客网 时间:2024/05/05 06:55

How far away ?

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11393 Accepted Submission(s): 4160


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
23 21 2 103 1 151 22 32 21 2 1001 22 1

Sample Output
1025100100

Source
ECJTU 2009 Spring Contest 


利用lca 求得树上任意两点的距离,只会模板....


离线在线什么的,根本不懂.....


/*http://blog.csdn.net/liuke19950717*/#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn=40005;const int maxm=25;int tot;int power[maxm];int head[maxn],edgenum;struct Edge{    int v,w,next;}edge[2*maxn];int ver[2*maxn],R[2*maxn],first[maxn],dir[maxn];int dp[2*maxn][maxm];bool vis[maxn];void init(){edgenum=0;memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));for(int i=0;i<maxm;++i){power[i]=(1<<i);}}void add(int u,int v,int w){Edge tp={v,w,head[u]};edge[edgenum]=tp;head[u]=edgenum++;}void dfs(int u,int dep){vis[u]=1;first[u]=++tot;ver[tot]=u;R[tot]=dep;for(int k=head[u];k!=-1;k=edge[k].next){if(!vis[edge[k].v]){int v=edge[k].v,w=edge[k].w;dir[v]=dir[u]+w;dfs(v,dep+1);ver[++tot]=u;R[tot]=dep;}}}void ST(int len){int k=(int)(log(len*1.0)/log(2.0));for(int i=1;i<=len;++i){dp[i][0]=i;}for(int j=1;j<=k;++j){for(int i=1;i+power[j]-1<=len;++i){int a=dp[i][j-1],b=dp[i+power[j-1]][j-1];if(R[a]<R[b]){dp[i][j]=a;}else{dp[i][j]=b;}}}}int RMQ(int x,int y){int k=(int)(log((y-x+1)*1.0)/log(2.0));int a=dp[x][k],b=dp[y-power[k]+1][k];if(R[a]<R[b]){return a;}return b;}int LCA(int u,int v){int x=first[u],y=first[v];if(x>y){swap(x,y);}int index=RMQ(x,y);return ver[index];}int main(){int t;scanf("%d",&t);while(t--){int n,m;scanf("%d%d",&n,&m);init();for(int i=0;i<n-1;++i){int a,b,len;scanf("%d%d%d",&a,&b,&len);add(a,b,len);add(b,a,len);}tot=dir[1]=0;dfs(1,1);ST(tot);for(int i=0;i<m;++i){int a,b,lca;scanf("%d%d",&a,&b);lca=LCA(a,b);printf("%d\n",dir[a]+dir[b]-2*dir[lca]);}}return 0;}


0 0
原创粉丝点击