题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2545
很裸的一道LCA,就是让你判断谁先到达他们的最近公共祖先。
如果用一个数组dis[]存储每一个节点到根节点的距离,那最后就是比较dis[a]-dis[LCA(a,b)] 与dis[b] - dis[LCA(a,b)]的大小
额。。好吧,写到这里的时候我发现了,最后不就可以转化成谁到树根的距离近么,,直接判断dis[a]与dis[b]的大小就好了
哎,是我2b了,,既然写到这里了就把这篇博客写完吧。
先找出root,然后dfs一次找出每个节点到root的距离,其实这个地方就可以结束了。
如果用LCA的话,因为是离线的算法,需要把要判断的两点再存储起来,然后用tarjan。
贴下我用LCA离线算法的代码吧。
code:
View Code
1 # include<stdio.h> 2 # include<string.h> 3 # define N 100005 4 struct node{ 5 int from,to,next; 6 }edge[2*N]; 7 struct node1{ 8 int from,to,num,next; 9 }edge1[2*N]; 10 int head[N],tol,dis[N],head1[N],tol1,father[N],visit[N],LCA[N],vis[N]; 11 void add(int a,int b) 12 { 13 edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++; 14 } 15 void add1(int a,int b,int c) 16 { 17 edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].num=c;edge1[tol1].next=head1[a];head1[a]=tol1++; 18 } 19 void dfs(int u,int father,int step) 20 { 21 int j,v; 22 dis[u]=step; 23 for(j=head[u];j!=-1;j=edge[j].next) 24 { 25 v=edge[j].to; 26 if(v==father) continue; 27 dfs(v,u,step+1); 28 } 29 } 30 int find(int x) 31 { 32 if(x!=father[x]) father[x]=find(father[x]); 33 return father[x]; 34 } 35 void tarjan(int u) 36 { 37 int j,v; 38 visit[u]=1; 39 father[u]=u; 40 for(j=head1[u];j!=-1;j=edge1[j].next) 41 { 42 v=edge1[j].to; 43 if(visit[v]) LCA[edge1[j].num]=find(v); 44 } 45 for(j=head[u];j!=-1;j=edge[j].next) 46 { 47 v=edge[j].to; 48 if(!visit[v]) 49 { 50 tarjan(v); 51 father[v]=u; 52 } 53 } 54 } 55 int main() 56 { 57 int i,n,m,a,b,c,root; 58 while(scanf("%d%d",&n,&m)!=EOF) 59 { 60 if(n==0 && m==0) break; 61 tol=0; 62 memset(head,-1,sizeof(head)); 63 memset(vis,0,sizeof(vis)); 64 for(i=1;i<n;i++) 65 { 66 scanf("%d%d",&a,&b); 67 add(a,b); 68 add(b,a); 69 vis[b]=1; 70 } 71 for(i=1;i<=n;i++) 72 if(vis[i]==0) break; 73 root=i; 74 dfs(root,0,0); 75 memset(head1,-1,sizeof(head1)); 76 tol1=0; 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 memset(visit,0,sizeof(visit)); 84 tarjan(root); 85 for(i=0;i<tol1;i+=2) 86 { 87 a=edge1[i].from; 88 b=edge1[i].to; 89 c=edge1[i].num; 90 if(dis[a]-dis[LCA[c]] <= dis[b]-dis[LCA[c]]) printf("lxh\n"); 91 else printf("pfz\n"); 92 } 93 } 94 return 0; 95 }