#include <iostream>
#include <vector>
#include <map>
#include <set>
using namespace std;
struct Node
{
int val;
vector<int> chlidren;
Node(int v):val(v){}
};
class UnSet
{
public:
UnSet(int n):capacity(n)
{
father = new int[n];
for(int i = 0; i < n ;i++)
{
father[i] = i;
}
}
~UnSet()
{
delete [] father;
}
int find(int i)
{
return (father[i] == i)?i:(father[i] = find(father[i]));
}
void unionSet(int a, int b)
{
a = find(a);
b = find(b);
father[b] = a;
}
int size()
{
return capacity;
}
int * father;
private:
int capacity;
};
class LCA
{
public:
LCA(Node tree[], int n):fatSet(n),capacity(n)//root is tree[0]
{
hasVisit = new bool[n];
memset(hasVisit,false,n*sizeof(bool));
this->tree = tree;
}
map<pair<int,int>,int> calLCA(vector<pair<int,int> > query)
{
map<int,set<int> > queryMap;
map<pair<int,int>,int> result;
for(int i =0 ; i< query.size(); i++)
{
int u = query[i].first;
int v = query[i].second;
set<int> temp;
if(queryMap.count(u) == 0)
queryMap[u] = temp;
if(queryMap.count(v) == 0)
queryMap[v] = temp;
queryMap[u].insert(v);
queryMap[v].insert(u);
}
tarjan(0,queryMap,result);
return result;
}
void tarjan(int u,map<int,set<int> > & queryMap, map<pair<int,int>,int> & result)
{
fatSet.father[u] = u;
hasVisit[u] = true;
cout << u << endl;
for(set<int>::iterator it = queryMap[u].begin(); it != queryMap[u].end();it++)
{
int v = *it;
if(hasVisit[*it])
{
pair<int,int> temp(v,u);
result[temp] = fatSet.find(v);
}
}
for(int i = 0; i < tree[u].chlidren.size(); i++)
{
int v = tree[u].chlidren[i];
if(false == hasVisit[tree[u].chlidren[i]])
{
tarjan(v,queryMap,result);
fatSet.unionSet(u,v);
}
}
}
private:
int capacity;
bool * hasVisit;
UnSet fatSet;
Node * tree;
};
int main()
{
Node testTree[5]={1,2,3,4,5};
testTree[0].chlidren.push_back(1);
testTree[0].chlidren.push_back(2);
testTree[1].chlidren.push_back(3);
testTree[1].chlidren.push_back(4);
vector<pair<int,int> > query;
pair<int,int> a(2,3),b(3,4),c(4,1);
query.push_back(a);
query.push_back(b);
query.push_back(c);
LCA l(testTree,5);
map<pair<int,int>,int> ret = l.calLCA(query);
for(map<pair<int,int>,int>::iterator it = ret.begin(); it != ret.end(); it++)
{
cout << it->first.first << "," << it->first.second << "->" << it->second << "\t";
}
return 0;
}
最小公共祖先(LCA)离线算法_Tarjan c++实现
最新推荐文章于 2024-08-18 21:16:02 发布