这两个地址看了就懂了
在这个网站看并查集:http://www.nocow.cn/index.php/%E5%B9%B6%E6%9F%A5%E9%9B%86
tarjan算法:http://noalgo.info/476.html
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int MAX = 10000;
int n,root;
bool flag[MAX];
vector<int> tree[MAX];
void inputTree()
{
cin >> n;
for (int i = 0; i != n; i++)
{
tree[i].clear();
flag[i] = false;
}
for (int i = 0; i != n-1; i++)
{
int t1, t2;
cin >> t1 >> t2;
tree[t1].push_back(t2);
flag[t2] = true;
}
for (int i = 0; i != n; i++)
if (flag[i] == false)
{
root = i;
break;
}
}
vector<int> query[MAX];
void inputQuery()
{
for (int i = 0; i != n; i++)
{
query[i].clear();
}
int m;
cin >> m;
while (m--)
{
int u,v;
cin >> u >> v;
query[u].push_back(v);
query[v].push_back(u);
}
}
int f[MAX], rnk[MAX];//表示秩(高度)
void makeSet()
{
for (int i = 0; i != n; i++)
{
f[i] = i;
rnk[i] = 0;
}
}
int findSet(int tmp)
{
int x = tmp;
while (x != f[x])
{
x = f[x];
}
int y = tmp,z;
while (y != x)
{
z = f[y];
f[y] = x;
y = z;
}
return x;
}
void unionSet(int x,int y)
{
x = findSet(x), y = findSet(y);
if (x == y)
return ;
if (rnk[x] > rnk[y])
f[y] = x;
else
f[x] = y,rnk[y] += rnk[x] == rnk[y];
}
int ancestor[MAX];
bool vis[MAX];
void tarjan(int x)
{
for (int i = 0; i != tree[x].size(); i++)
{
tarjan(tree[x][i]);
unionSet(x,tree[x][i]);
ancestor[findSet(x)] = x;
}
vis[x] = true;
for (int i = 0; i < query[x].size(); i++)
{
if (vis[query[x][i]])
printf("%d he %d ancestor is %d\n",x,query[x][i],ancestor[findSet(query[x][i])]);
}
}
int main()
{
inputTree(); //输入树
inputQuery();//输入查询
makeSet();
for (int i = 0; i < n; i++) ancestor[i] = i;
memset(vis, 0, sizeof(vis)); //初始化为未访问
tarjan(root);
return 0;
}