标签:
///Nearest Common Ancestors /// 1330 #include <cstdio> #include <map> #include <cstring> #include <vector> using namespace std; const int maxn = 10000+10; int t,n; vector<int> v[maxn],Q[maxn]; int p[maxn]; int ind[maxn]; int ancester[maxn]; int vis[maxn]; int make_set(int x){ p[x]=x; } int find_set(int a){ return a==p[a]?a:find_set(p[a]); } int union_set(int a,int b){ int pa = find_set(a); int pb = find_set(b); if(pa != pb){ p[pb] = pa; } } void LCA(int t){ make_set(t); ancester[t]=t; for(int i=0;i<v[t].size();i++){ LCA(v[t][i]); union_set(t,v[t][i]); ancester[v[t][i]] = t; } vis[t] = 1; for(int i=0;i<Q[t].size();i++){ if(vis[Q[t][i]] == 1){ printf("%d\n",ancester[find_set(Q[t][i])]); return; } } } int main(){ scanf("%d",&t); while(t--){ memset(ind,0,sizeof(ind)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(int i=1;i<=n;i++){ v[i].clear(); Q[i].clear(); } for(int i=0;i<n-1;i++){ int U,V; scanf("%d %d",&U,&V); v[U].push_back(V); ind[V]+=1; } int q1,q2; scanf("%d %d",&q1,&q2); ///查询集合{u,v}, ///我们构造临界表u->v,v->u, ///这样我们用u可以调用v,用v调用u, ///模拟函数f(x), ///定义f,基数为2的集合V中f(x)=V-x. Q[q1].push_back(q2); Q[q2].push_back(q1); for(int i=1;i<=n;i++){ if(!ind[i]){ LCA(i); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/Lxyan/p/5516468.html