NOIP级别 祖孙询问 LCA 解题报告
2017-07-21 15:53
204 查看
【问题描述】
已知一棵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。【样例输入】
10234 -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
【样例输出】
10
0
0
2
【数据规模】
对于30%的数据,n,m≤1000。对于100%的.据,n,m≤40000,每个节点的编号都不超过40000。
思路
LCA就好了。不过这道题的询问很水,用DFS序扫一遍记录下来也可以。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=40000+5; int bin[16],n,m,root,num; int q ,deep ,fa [16],head ; bool vis ; struct edge { int v,next; } edge ed[2*N]; void build(int u,int v) { ed[++num].v=v; ed[num].next=head[u]; head[u]=num; } void bfs() { int head=0,tail=1; q[0]=root;vis[root]=1; while(head!=tail) { int now=q[head]; head++; for (int i=1;i<=15;i++) if (bin[i]<=deep[now]) fa[now][i]=fa[fa[now][i-1]][i-1]; else break; for (int i=head[now];i;i=ed[i].next) if (!vis[ed[i].v]) { deep[ed[i].v]=deep[now]+1; fa[ed[i].v][0]=now; vis[ed[i].v]=1; q[tail++]=ed[i].v; } } } int LCA(int x,int y) { int t; if (deep[x]<deep[y]) swap(x,y); t=deep[x]-deep[y]; for (int i=0;i<=15;i++) if (t&bin[i]) x=fa[x][i]; for (int i=15;i>=0;i--) if (fa[x][i]!=fa[y][i]) {x=fa[x][i];y=fa[y][i];} if (x==y) return y; return fa[x][0]; } int main() { bin[0]=1; for(int i=1;i<=15;i++) bin[i]=bin[i-1]*2; scanf("%d",&n); for(int i=1;i<=n;i++) { int u,v; scanf("%d%d",&u,&v); if (v==-1) root=u; else { build(u,v); build(v,u); } } bfs(); scanf("%d",&m); for(int i=1;i<=m;i++) { int a,b,t; scanf("%d%d",&a,&b); t=LCA(a,b); if (a==t&&b!=t) printf("1"); else if (a!=t&&b==t) printf("2"); else printf("0"); } return 0; }
相关文章推荐
- Luogu1967 [NOIP2013] 货车运输 解题报告【Kruskal】【LCA】【倍增】
- LuoguP2680/UOJ150[NOIP2015] 运输计划 解题报告【二分答案+树上操作(LCA)+树上差分】
- NOIP2013 货车运输 解题报告(最大生成树+倍增lca)
- NOIP2013 积木大赛 解题报告(贪心)
- codevs 1036 商务旅行 LCA 解题报告
- 2016.8.25 NOIP2012 day1 解题报告
- NOIP2016Day2T2蚯蚓解题报告
- noip2006提高组-金明的预算方案解题报告
- NOIP2014 解题报告·水渣记
- NOIP2015信息传递解题报告
- NOIP2007 T2纪念品分组 解题报告-S.B.S.
- LuoguP1038[NOIP2003] 神经网络 解题报告【拓扑排序+DP/递推】
- NOIP2011提高组 聪明的质检员(重庆一中高2018级信息学竞赛测验6) 解题报告
- NOIP 2008 解题报告(笨小猴,火柴棒等式,传纸条,双栈排序)
- JZOJ.4302[NOIP2015模拟11.3]IOIOI卡片占卜 解题报告
- hdu 2586 How far away? 【LCA】 解题报告
- 全国信息学奥林匹克联赛(NOIP2010)复赛 3.导弹拦截 解题报告
- NOIP2011 选择客栈 解题报告(DP)
- 10 noip 机器翻译 解题报告