题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
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. 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个房屋,这些房屋之间的链接是树形链接,房屋和房屋之间有且只有一个路线;道路是双向的。
T组数据;
n个房子,m次查询;
n-1个路径 :a,b之间的距离是l
每次查询输出a,b之间的距离;
题非常简单,只是在板子上加个len数组记录一下长度即可,观察LCA板子和这个代码,发现没有什么去别.....
注意。。n是4e4....之前一直习惯1e6..也没怎么改,就交了好几发的MLE...
ac:
//#pragma comment(linker, "/STACK:1024000000,1024000000") //啥玩意??我看大佬们都写个这个,也不知道有啥用...就写上吧...
#include<stdio.h>
#include<string.h>
#include<math.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
const int MAXN=40000+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
struct node{
int v,w,cost,nxt;
node(int _v=0,int _w=0,int _nxt=0):
v(_v),w(_w),nxt(_nxt){}
}edge[MAXN<<1];
int head[MAXN<<1],ecnt;
int fa[MAXN][30],deep[MAXN];
ll len[MAXN][30];
int n,m;
void intt()
{
clean(head,-1);
clean(fa,-1);
clean(deep,0);
clean(len,0);
ecnt=0;
}
void add(int u,int v,int w)
{
edge[ecnt]=node(v,w,head[u]);
head[u]=ecnt++;
}
/*---上面的是板子,不用动---*/
void dfs(int u)
{
for(int i=head[u];i+1;i=edge[i].nxt)
{
int temp=edge[i].v;
if(deep[temp]==0)
{
deep[temp]=deep[u]+1;
fa[temp][0]=u;
len[temp][0]=edge[i].w;//就加一个len数组...
int up=0,pre=u;
while(fa[pre][up]>=0)
{
fa[temp][up+1]=fa[pre][up];
len[temp][up+1]=len[pre][up]+len[temp][up];//记得len数组刷新
pre=fa[pre][up++];
}
dfs(temp);
}
}
}
ll lca(int a,int b)
{
ll ans=0;//记录总长
if(deep[a]<deep[b])
swap(a,b);
int lim=log2(deep[a])+1;
for(int i=lim;i>=0;--i)
{
if(deep[fa[a][i]]>=deep[b])
{
ans=ans+len[a][i];//刷新
a=fa[a][i];
}
}
if(a==b)
return ans;
for(int i=lim;i>=0;--i)
{
if(fa[a][i]!=fa[b][i])
{
ans=ans+len[a][i];//先刷新
a=fa[a][i];
ans=ans+len[b][i];
b=fa[b][i];
}
}
ans=ans+len[a][0]+len[b][0];
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--)
{
intt();
cin>>n>>m;
int a,b,l;
for(int i=1;i<n;++i)
{
cin>>a>>b>>l;
add(a,b,l);
add(b,a,l);
}
deep[1]=1;
dfs(1);
for(int i=1;i<=m;++i)
{
cin>>a>>b;
cout<<lca(a,b)<<endl;
}
}
}