标签:NPU head 个数 包括 orm dfs 编号 nta tin
#include <stdio.h> #define re register inline void read(int &x) { x=0;char c=getchar();bool p=1; for(; ‘0‘>c || c>‘9‘; c=getchar()) if(c==‘-‘) p=0; for(; ‘0‘<=c && c<=‘9‘; c=getchar()) x=(x<<1)+(x<<3)+(c^48); p?:x=-x; } struct node {int to,next;}; node edge[80001]; int cnt; int head[40001],d[40001]; int fa[40001][18]; inline void add(int u,int v) { edge[++cnt]=(node){v,head[u]}; head[u]=cnt; } inline void dfs(int u) { for(re int i=1; i<=17; ++i) { if(d[u]<(1<<i)) break; fa[u][i]=fa[fa[u][i-1]][i-1]; } for(re int i=head[u]; i; i=edge[i].next) { int v=edge[i].to; if(v==fa[u][0]) continue; fa[v][0]=u; d[v]=d[u]+1; dfs(v); } } inline int LCA(int u,int v) { if(d[u]<d[v]) u^=v,v^=u,u^=v; for(re int i=0; i<=17; ++i) if((d[u]-d[v])&(1<<i)) u=fa[u][i]; if(u==v) return u; for(re int i=17; i>=0; --i) if(fa[u][i]^fa[v][i]) u=fa[u][i],v=fa[v][i]; return fa[u][0]; } int main() { int N,root; read(N); for(re int i=1; i<=N; ++i) { int A,B; read(A),read(B); if(B^-1) add(A,B),add(B,A); else root=A; } dfs(root); int M; read(M); for(re int i=1; i<=M; ++i) { int X,Y; read(X),read(Y); if(X^Y) { int l=LCA(X,Y); if(l==X) puts("1"); else if(l==Y) puts("2"); else puts("0"); } else puts("0"); } return 0; }
已知一棵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。
标签:NPU head 个数 包括 orm dfs 编号 nta tin
原文地址:https://www.cnblogs.com/Retr67/p/9534555.html