【题目描述】
方方方种下了三棵树,一年后,第一棵树长出了n个节点。
方方方会向你提出m个询问,每个询问给出两个数i,j,你需要回答i号节点和j号节点在树上的距离。
【输入数据】
第一行两个整数n,m。接下来n-1行每行两个整数a,b表示一条边。接下来m行每行两个整数i,j表示询问。
【输出数据】
m行,每行一个整数表示答案。
【样例输入】
3 2
1 2
1 3
3 2
1 1
【样例输出】
2
0
【数据范围】
对于30%的数据,n,m<=1000。
对于100%的数据,n,m<=500000。
题解:啊mdzz写个LCA啊。。。A到B的距离不就是A到根节点,B到根节点的距离之和减去(LCA到根节点的距离的两倍),今天学了个比较有趣的LCA。。QAQ
传教时间到!
1 #include<stdio.h> 2 #include<string.h> 3 #include <iostream> 4 #include <cmath> 5 #include <string> 6 #include <algorithm> 7 struct node 8 { 9 int from,to,next,val; 10 }edge[2*500001]; 11 struct node1 12 { 13 int from,to,next,num; 14 }edge1[2*500001]; 15 int tol,head[500001],head1[500001],cnt1,father[500001],dis[500001],LCA[500001],n,m; 16 bool visit[500001]; 17 void add(int a,int b,int c) 18 { 19 edge[tol].from=a; 20 edge[tol].to=b; 21 edge[tol].next=head[a]; 22 edge[tol].val=c; 23 head[a]=tol++; 24 } 25 void add1(int a,int b,int c) 26 { 27 edge1[cnt1].from=a; 28 edge1[cnt1].to=b; 29 edge1[cnt1].next=head1[a]; 30 edge1[cnt1].num=c; 31 head1[a]=cnt1++; 32 } 33 int find(int x) 34 { 35 if(x!=father[x]) 36 father[x]=find(father[x]); 37 return father[x]; 38 } 39 void tarjan(int u) 40 { 41 int j; 42 visit[u]=1; 43 father[u]=u; 44 for(j=head1[u];j!=-1;j=edge1[j].next) 45 { 46 int temp=edge1[j].to; 47 if (visit[temp]) 48 LCA[edge1[j].num]=find(temp); 49 } 50 for(j=head[u];j!=-1;j=edge[j].next) 51 { 52 int temp=edge[j].to; 53 if(!visit[edge[j].to]) 54 { 55 dis[temp]=dis[u]+edge[j].val; 56 tarjan(temp); 57 father[temp]=u; 58 } 59 }//xjb dfs... 60 } 61 int main() 62 { 63 int i,a,b; 64 freopen("tree.in","r",stdin); 65 freopen("tree.out","w",stdout); 66 scanf("%d%d",&n,&m); 67 tol=0,cnt1=0; 68 memset(head,-1,sizeof(head)); 69 memset(visit,0,sizeof(visit)); 70 memset(head1,-1,sizeof(head1)); 71 for(i=1;i<=n-1;i++) 72 { 73 scanf("%d%d",&a,&b); 74 add(a,b,1); 75 add(b,a,1); 76 } 77 for(i=1;i<=m;i++) 78 { 79 scanf("%d%d",&a,&b); 80 add1(a,b,i); 81 add1(b,a,i); 82 } 83 dis[1]=0; 84 tarjan(1); 85 for(i=0;i<=cnt1-1;i+=2) 86 printf("%d\n",dis[edge1[i].from]+dis[edge1[i].to]-2*dis[LCA[edge1[i].num]]); 87 return 0; 88 }
传教时间到!
啊这个代码比较核心。。↓
1 int find(int x) 2 { 3 if (x!=father[x]) 4 father[x]=find(father[x]); 5 return x; 6 void tarjan(int u) 7 { 8 visit[u]=1; 9 father[u]=u; 10 for (i=g2[u];i!=-1;i=e2[i].next) 11 if (visit[e2[i].to]) 12 LCA[e2[i].num]=find(e2[i].to); 13 for (i=g[u];i!=-1;i=e[i].next) 14 { 15 if (!visit[e[i].to]) 16 { 17 dis[e[i].to]=dis[u]+e[i].w; 18 tarjan(w[i].to); 19 father[e[i].to]=u; 20 } 21 } 22 23 }
QAQ
啊今天只写过了第一题QAQ。。要完啊
时间: 2024-10-07 13:36:36