poj 1330 Nearest Common Ancestors(离线LCA)

来源:互联网 发布:hiteach软件在哪买 编辑:程序博客网 时间:2024/05/09 07:16

题目链接:http://poj.org/problem?id=1330

题意:T组样例,n-1条边,1次询问,求最近公共祖先。


#include<iostream>#include<cstdio>#include<vector>using namespace std;const int INF=0x3f3f3f3f;const int maxn=10010;int T,n;int degree[maxn],vis[maxn];int ancestor[maxn];vector<int>tree[maxn];vector<int>query[maxn];int f[maxn],r[maxn];void Make_Set(){for(int i=0;i<=n;i++){f[i]=i;r[i]=1;}}int find(int x){return x==f[x]?x:f[x]=find(f[x]);}void Union(int a,int b){int ra=find(a);int rb=find(b);if(ra==rb) return ;if(r[ra]>r[rb]){f[rb]=ra;r[ra]+=r[rb];}else{f[ra]=rb;r[rb]+=r[ra];}}void Tarjan(int root){for(int i=0;i<tree[root].size();i++){if(!vis[tree[root][i]]){Tarjan(tree[root][i]);Union(root,tree[root][i]);ancestor[find(root)]=root;}}vis[root]=1;for(int i=0;i<query[root].size();i++){if(vis[query[root][i]]){printf("%d\n",ancestor[find(query[root][i])]);}}}void Init(){Make_Set();memset(vis,0,sizeof(vis));memset(degree,0,sizeof(degree));for(int i=0;i<=n;i++){tree[i].clear();query[i].clear();ancestor[i]=i;}}int main(){#ifndef ONLINE_JUDGEfreopen("test.in","r",stdin);freopen("test.out","w",stdout);#endifscanf("%d",&T);while(T--){scanf("%d",&n);Init();int x,y;for(int i=0;i<n-1;i++){scanf("%d%d",&x,&y);tree[x].push_back(y);degree[y]++;}scanf("%d%d",&x,&y);query[x].push_back(y);query[y].push_back(x);int root;for(int i=1;i<=n;i++){if(!degree[i]){root=i;break;}}Tarjan(root);}return 0;}


0 0