hdu 2545 树上战争

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

 

 

你可能感兴趣的:(HDU)