UESTC_树上战争 CDOJ 32

给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxhpfz初始时分别站在两个节点上,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜。

Input

输入包含多组数据

每组第一行包含两个数N,M(N,M100000),N表示树的节点数,M表示询问数,N=M=0表示输入结束。节点的编号为1N

接下来N1行,每行2个整数A,B(1A,BN),表示编号为A的节点是编号为B的节点的父亲。

接下来M行,每行有2个数,表示lxhpfz的初始位置的编号X,Y(1X,YN,XY),lxh总是先移动。

Output

对于每次询问,输出一行,输出获胜者的名字。

Sample input and output

Sample InputSample Output
2 1
1 2
1 2
5 2
1 2
1 3
3 4
3 5
4 2
4 5
0 0
lxh
pfz
lxh

解题报告

即求到根的距离,采用记忆化搜索..

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdbool.h>
 4 #include <stdlib.h>
 5 #define maxn 100005
 6 
 7 int pre[maxn];
 8 int dis[maxn];
 9 
10 
11 int setdis(int id)
12 {
13   if (dis[id] != -1)
14    return dis[id];
15   dis[id] = 0;
16   if (pre[id] != id)
17    dis[id] = setdis(pre[id])+1;
18  return dis[id];
19 }
20 
21 
22 
23 int main(int argc , char * argv[])
24 {
25  int i,j,n,m;
26  while(scanf("%d%d",&n,&m))
27   {
28       if (!n && !m)
29        break;
30       for(i = 0 ; i < n ; ++ i)
31          pre[i] = i;
32       memset(dis,-1,sizeof(dis));
33       for(i = 0 ; i < n-1 ; ++ i)
34        {
35          int a,b;
36          scanf("%d%d",&a,&b);
37          pre[b-1] = a-1;
38      }
39     for(i = 0 ; i < m ; ++ i)
40      {
41          int p1 , p2;
42          scanf("%d%d",&p1,&p2);
43          if (dis[p1-1] == -1)
44           setdis(p1-1);
45          if (dis[p2-1] == -1)
46           setdis(p2-1);
47          if (dis[p1-1] <= dis[p2-1])
48           printf("lxh
");
49          else
50           printf("pfz
");
51      }
52   }
53  return 0;
54 }
No Pain , No Gain.
原文地址:https://www.cnblogs.com/Xiper/p/4465691.html