给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxh
和pfz
初始时分别站在两个节点上,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜。
Input
输入包含多组数据
每组第一行包含两个数N,M(N,M≤100000),N表示树的节点数,M表示询问数,N=M=0表示输入结束。节点的编号为1到N。
接下来N−1行,每行2个整数A,B(1≤A,B≤N),表示编号为A的节点是编号为B的节点的父亲。
接下来M行,每行有2个数,表示lxh
和pfz
的初始位置的编号X,Y(1≤X,Y≤N,X≠Y),lxh
总是先移动。
Output
对于每次询问,输出一行,输出获胜者的名字。
Sample input and output
Sample Input | Sample 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 }