URAL
来源:互联网 发布:c语言字母大小互换程序 编辑:程序博客网 时间:2024/04/28 04:03
Galactic History
题目链接:Galactic History
题意:给你一棵树,每一行两个点的意思就是后一个节点是前一个节点的父亲节点,当后一个节点为-1时,说明前一个节点为这棵树的根。
然后有L次询问,对于每一次询问,如果前一个节点是后一个节点的祖先节点就输出1,后一个节点是前一个节点的祖先节点就输出2,否则就输出0
思路:类似与对每一个节点进行标号,从树的根节点开始遍历,左端点记录当前节点的位置,右端点记录当前节点的最后一个子节点的位置,这样每一个节点的左右端点表示的就是[自身的位置,最后一个子节点的位置],也就相当于这个区间存储了它的每一个子节点
询问的时候只需要判断一个点的区间是否被另一个点的区间所包围就行了
ps:思路是队友想的,不得不佩服队友的强大,真是开阔了思路
代码:
#include<stdio.h>#include<vector>#include<string.h>using namespace std;#define maxn 40010vector<int>q[maxn];int le[maxn],ri[maxn];int n,root,m,len;void dfs(int x){ le[x]=len; for(int i=0;i<q[x].size();++i) { ++len; dfs(q[x][i]); } ri[x]=len;}int main(){ scanf("%d",&n); int u,v; for(int i=0;i<n;++i) { scanf("%d%d",&u,&v); if(v==-1) { root=u; continue; } q[v].push_back(u); } len=1; dfs(root); scanf("%d",&m); for(int i=0;i<m;++i) { scanf("%d%d",&u,&v); if(le[u]<=le[v]&&ri[v]<=ri[u]) printf("1\n"); else if(le[v]<=le[u]&&ri[u]<=ri[v]) printf("2\n"); else printf("0\n"); } return 0;}
1 0