推薦部落格:http://kmplayer.iteye.com/blog/604518
poj 1330
原始碼:
#include <stdio.h>#include <vector>#define MAXN 10005using namespace std;vector<int>tree[MAXN];vector<int>query[MAXN];int n,q;int s,t,cas;int f[MAXN],visit[MAXN]; //MAXN為節點編號的最大值int degree[MAXN]; //記錄入度int ancestor[MAXN]; //記錄某一個並查集的祖先int r[MAXN]; //深度void Init(){ for(int i=1;i<=n;i++) { r[i]=1; visit[i]=0; f[i]=i; ancestor[i]=i; degree[i]=0; tree[i].clear(); query[i].clear(); }}int find(int x){ if(x==f[x]) return x; else { f[x]=find(f[x]); return f[x]; }}int Uion(int x,int y) //合并成功返回1,合并不成功返回0{ int a=find(x); int b=find(y); if(a==b) return 0; if(r[a]>r[b]) { r[a]+=r[b]; f[b]=a; } else { r[b]+=r[a]; f[a]=b; } return 1;}void lca(int u){ for(int i=0;i<tree[u].size();i++) { lca(tree[u][i]); Uion(tree[u][i],u); ancestor[find(u)]=u; } visit[u]=1; for(int i=0;i<query[u].size();i++) { if(visit[query[u][i]]==1) { printf("%d\n",ancestor[find(query[u][i])]); } }}int main(){ freopen("D:\\a.txt","r",stdin); scanf("%d",&cas); while(cas--){ scanf("%d",&n); Init(); for(int i=1;i<n;i++) { scanf("%d %d",&s,&t); //s[i]是父節點,t[i]是子節點 tree[s].push_back(t); degree[t]++; } //scanf("%d",&q); // for(int i=0;i<q;i++) // { scanf("%d %d",&s,&t); //查詢s,t的最近公用祖先 query[s].push_back(t); query[t].push_back(s); // } for(int i=1;i<=n;i++) { if(degree[i]==0) { lca(i); break; } } } return 0;}