标签:
Description
Input
Output
Sample Input
2 16 1 14 8 5 10 16 5 9 4 6 8 4 4 10 1 13 6 15 10 11 6 7 10 2 16 3 8 1 16 12 16 7 5 2 3 3 4 3 1 1 5 3 5
Sample Output
4 3 【分析】这题就是求最近公共祖先,让我对Tarjan有了一个新的认识。先找到根节点,一直往下深搜,
找到子节点,若该节点就是要求的点且另一个点已经被访问过,则另一个点所在并查集的根节点即为最近公共祖先。
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 1000000007 typedef long long ll; using namespace std; const int N = 100005; int fa[N],node1,node2,ret; bool root[N],visit[N]; vector<int>child[N]; int Find(int x) { if(x==fa[x]) return x; return fa[x]=Find(fa[x]); } void Union(int x,int y) { x=Find(x); y=Find(y); fa[y]=x; } void Tarjan(int root) { fa[root]=root;visit[root]=true; for(int i=0;i<child[root].size();i++) { Tarjan(child[root][i]); Union(root,child[root][i]); } if(root==node1&&visit[node2]) { ret=fa[Find(node2)]; return ; } if(root==node2&&visit[node1]) { ret=fa[Find(node1)]; return ; } } int main() { int T,n,i; scanf("%d",&T); while(T--) { memset(visit,false,sizeof(visit)); scanf("%d",&n); for(i=1;i<=n;i++) { root[i]=true; child[i].clear(); } for(i=1;i<=n-1;i++) { int a,b; scanf("%d%d",&a,&b); child[a].push_back(b); root[b]=false;//寻找root } scanf("%d%d",&node1,&node2); for(i=1;i<=n;i++) if(root[i]) { Tarjan(i); break; } printf("%d\n",ret); } }
POJ1330 Nearest Common Ancestors(最近公共祖先)(tarjin)
标签:
原文地址:http://www.cnblogs.com/jianrenfang/p/5740529.html