|
中文题目名称 |
祖孙询问 |
比赛 |
数字 |
|
英文题目名称 |
tree |
mat |
num |
|
可执行文件名 |
tree |
mat |
num |
|
输入文件名 |
tree.in |
mat.in |
num.in |
|
输出文件名 |
tree.out |
mat.out |
num.out |
|
每个测试点时限 |
1秒 |
1秒 |
1秒 |
|
测试点数目 |
10 |
10 |
10 |
|
每个测试点分值 |
10 |
10 |
10 |
|
附加样例文件 |
有 |
有 |
有 |
|
题目类型 |
传统 |
传统 |
传统 |
二. 提交源程序文件名
|
对于pascal语言 |
tree.pas |
mat.pas |
num.pas |
|
对于C语言 |
tree.c |
mat.c |
num.c |
|
对于C++语言 |
tree.cpp |
mat.cpp |
num.cpp |
三. 编译命令(不包含任何优化开关)
|
对于pascal语言 |
fpc tree.pas |
fpc mat.pas |
fpc num.pas |
|
对于C语言 |
gcc –o tree tree.c -lm |
gcc –o mat mat.c -lm |
gcc –o num num.c -lm |
|
对于C++语言 |
g++ -o tree tree.cpp -lm |
g++ -o mat mat.cpp -lm |
g++ -o num num.cpp -lm |
四. 运行内存限制
|
内存上限 |
128M |
128M |
128M |
五. 注意事项
1、 文件名(程序名和输入输出文件名)必须使用小写。
2、 C/C++中函数main()的返回值类型必须是int,程序正常结束时的返回值必须是0。
3、 全国统一评测时采用的机器配置为:CPU 1.9GHz,内存1G,上述时限以此配置为准。各省在自测时可根据具体配置调整时限。
祖孙询问
(tree.pas/c/cpp)
【问题描述】
已知一棵n个节点的有根树。有m个询问。每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。
【输入格式】
输入第一行包括一个整数n表示节点个数。
接下来n行每行一对整数对a和b表示a和b之间有连边。如果b是-1,那么a就是树的根。
第n+2行是一个整数m表示询问个数。
接下来m行,每行两个正整数x和y。
【输出格式】
对于每一个询问,输出1:如果x是y的祖先,输出2:如果y是x的祖先,否则输出0。
【样例输入】
10
234 -1
12 234
13 234
14 234
15 234
16 234
17 234
18 234
19 234
233 19
5
234 233
233 12
233 13
233 15
233 19
【样例输出】
1
0
0
0
2
【数据规模】
对于30%的数据,n,m≤1000。
对于100%的.据,n,m≤40000,每个节点的编号都不超过40000。
LCA:
#include<iostream> #include<cstdio> #include<cstring> #define maxn 50010 using namespace std; int N,n,m,root,num,head[maxn],dep[maxn],fa[maxn][25]; struct node{ int v,pre; }e[maxn*2]; int init(){ int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } void Add(int from,int to){ num++;e[num].v=to; e[num].pre=head[from]; head[from]=num; } void Dfs(int now,int from,int c){ fa[now][0]=from;dep[now]=c; for(int i=head[now];i;i=e[i].pre){ int v=e[i].v; if(v==from)continue; Dfs(v,now,c+1); } } void Get_fa(){ for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; } int LCA(int a,int b){ if(dep[a]<dep[b])swap(a,b); int t=dep[a]-dep[b]; for(int i=0;i<=20;i++) if((1<<i)&t)a=fa[a][i]; if(a==b)return a; for(int i=20;i>=0;i--) if(fa[a][i]!=fa[b][i]){ a=fa[a][i]; b=fa[b][i]; } return fa[a][0]; } int main() { freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); N=init(); int u,v; for(int i=1;i<=N;i++){ u=init();v=init(); if(v==-1){ root=u;continue; } if(u==-1){ root=v;continue; } n=max(n,u);n=max(n,v); Add(u,v);Add(v,u); } Dfs(root,-1,0);Get_fa(); m=init(); for(int i=1;i<=m;i++){ u=init();v=init(); if(u==v){ printf("0\n"); continue; } int anc=LCA(u,v); if(anc==u)printf("1\n"); else if(anc==v)printf("2\n"); else printf("0\n"); } return 0; }