InputFirst 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.OutputFor 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-1条边, 也就是1颗带权树
问:树上点与点之间的最近距离是多少?
有m次查询
给两个点的编号
输出两个点之间的最近距离
做法:
SA算法
将LCA问题转换成RMQ问题
首先需要求三个数组
一个数组是dfs时每个点的访问序列,设这个数组为 dfsf[]
一个数组是每个节点dfs时第一次出现的位置,设这个数组为 first[]
一个数组是每个节点对应的深度,设这个数组为 deep[]
如果询问l,r的最近公共祖先
就是询问在dfsf数组里 first[l]到first[r] 节点 这个区间内的深度最小的节点时哪个节点?
使用ST算法求解这个RMQ问题即可。
代码:
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cstring> 5 #include<vector> 6 const int maxn = 50000; 7 struct bian{ 8 int p; 9 int w; 10 }; 11 vector<int> dfsf; 12 vector<bian> maps[maxn]; 13 int fa[maxn]; 14 int v[maxn]; 15 int deep[maxn]; 16 int first[maxn]; 17 template<class T> 18 class RMQ{ 19 public: 20 T* a; 21 int t; 22 T **mn; 23 T maxn; 24 int *log2; 25 void SetMaxn(T *maxn){ 26 this->maxn=*maxn; 27 } 28 void SetMaxn(T maxn){ 29 this->maxn=maxn; 30 } 31 void Creat(int maxn){//建立一个最大为maxn的RMQ处理类 32 int k=1,p=0; 33 log2=new int[maxn+10]; 34 for(int i=0;i<=maxn;i++) 35 log2[i]=(i==0?-1:log2[i>>1]+1); 36 while(k<maxn){ 37 k*=2; 38 p+=1; 39 } 40 t=p; 41 mn=new T*[maxn+10]; 42 for(int i=1;i<=maxn;++i){ 43 mn[i] = new T[t+1]; 44 mn[i][0]=dfsf[i-1]; 45 } 46 for(int j=1;j<=t;++j) 47 for(int i=1;i+(1<<j) <= maxn;++i){ 48 T sa=deep[mn[i][j-1]]; 49 T sb=deep[mn[i+(1<<(j-1))][j-1]]; 50 if(sa<sb) 51 mn[i][j]=mn[i][j-1]; 52 else 53 mn[i][j]=mn[i+(1<<(j-1))][j-1]; 54 } 55 } 56 T Getx(int ql,int qr){ 57 int k=log2[qr-ql+1]; 58 if(deep[mn[ql][k]]<=deep[mn[qr-(1<<k)+1][k]]) 59 return mn[ql][k]; 60 else 61 return mn[qr-(1<<k)+1][k]; 62 } 63 T Getw(int ql,int qr){ 64 int k=log2[qr-ql+1]; 65 if(deep[mn[ql][k]]<=deep[mn[qr-(1<<k)+1][k]]) 66 return mn[ql][k]; 67 else 68 return mn[qr-(1<<k)+1][k]; 69 } 70 } ; 71 RMQ<int> rr; 72 int n,m; 73 void dfs(int x,int d){ 74 v[x]=1; 75 dfsf.push_back(x); 76 if(first[x]==0) 77 first[x] = dfsf.size(); 78 deep[x] = d; 79 for(int i=0;i<maps[x].size();i++){ 80 int point = maps[x][i].p; 81 if(v[point]) 82 continue; 83 fa[point]=x; 84 dfs(point,d+maps[x][i].w); 85 dfsf.push_back(x); 86 } 87 } 88 void deal(){ 89 scanf("%d%d",&n,&m); 90 for(int i=0;i<=n;i++) 91 maps[i].clear(); 92 memset(v,0,sizeof(v)); 93 memset(fa,0,sizeof(fa)); 94 memset(first,0,sizeof(first)); 95 dfsf.clear(); 96 for(int i=0;i<n-1;i++){ 97 int l,r,w; 98 scanf("%d%d%d",&l,&r,&w); 99 bian pt; 100 pt.p=r;pt.w=w; 101 maps[l].push_back(pt); 102 pt.p=l; 103 maps[r].push_back(pt); 104 } 105 dfs(1,0); 106 rr.Creat(dfsf.size()); 107 int l,r,dl,dr; 108 for(int i=0;i<m;i++){ 109 scanf("%d%d",&l,&r); 110 int ll,rrr; 111 ll=first[l],rrr=first[r]; 112 //cout<<"first: "<<ll<<" "<<rrr<<endl; 113 if(ll>rrr) 114 swap(ll,rrr); 115 int k=rr.Getw(ll,rrr); 116 int ans=0; 117 ans+=deep[k]-deep[l]; 118 ans+=deep[k]-deep[r]; 119 // cout<<"root "<<k<<endl; 120 if(ans<0) 121 ans=0 - ans; 122 printf("%d\n",ans); 123 } 124 } 125 int main(){ 126 int t; 127 scanf("%d",&t); 128 while(t--) 129 deal(); 130 return 0; 131 }