题目链接: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 }

 

 

posted on 2012-05-07 20:20  奋斗青春  阅读(197)  评论(0编辑  收藏  举报