给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,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
2 1 1 2 1 2 5 2 1 2 1 3 3 4 3 5 4 2 4 5 0 0
Sample Output
lxh pfz lxh 提示:
本题输入、输出都很多,请使用scanf和printf代替cin、cout。
我觉得这个题应该算水题(QAQ但是打比赛是没有看出来),
思路:维护一个树,然后用一个数组维护它的深度就行了。
AC:代码(592ms)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e5+5;
int n,m;
int vis[maxn],v[maxn];
int update(int x){
if(x==v[x]) return 0;
if(vis[x]!=0) return vis[x];
return vis[x] = update(v[x])+1;
}
int main()
{
while(~scanf("%d%d",&n,&m) && (n+m))
{
memset(vis,0,sizeof(vis));
memset(v,0,sizeof(v));
int a,b;
for(int i = 1;i<=n-1;i++){
scanf("%d %d",&a,&b);
v[b] = a;
}
//for(int i = 1;i<=n;i++) printf("%d ",v[i]);
//printf("
");
int c = n;
for(int i = 1;i<=n;i++) update(i);
//for(int i = 1;i<=n;i++) printf("%d ",vis[i]);
//printf("
");
for(int i = 1;i<=m;i++){
scanf("%d %d",&a,&b);
//printf("%d %d
",vis[a],vis[b]);
if(vis[a]<=vis[b]) printf("lxh
");
if(vis[a]>vis[b]) printf("pfz
");
}
}
return 0;
}