Pagini recente » Cod sursa (job #536538) | Cod sursa (job #1470290) | Cod sursa (job #1980771) | Cod sursa (job #3123396) | Cod sursa (job #995998)
Cod sursa(job #995998)
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
class DisjointSets {
public:
DisjointSets(const int setSize = 0) {
this->setSize = setSize;
father = vector<int>(setSize, NIL);
rank = vector<int>(setSize, 0);
size = vector<int>(setSize, 1);
}
int Find(const int x) {
if (father[x] == NIL)
return x;
return father[x] = Find(father[x]);
}
int Size(const int x) {
return size[Find(x)];
}
bool Merge(int x, int y) {
x = Find(x);
y = Find(y);
if (x == y)
return false;
if (rank[x] < rank[y])
swap(x, y);
father[y] = x;
rank[x] = max(rank[x], rank[y] + 1);
size[x] += size[y];
return true;
}
private:
static const int NIL = -1;
int setSize;
vector<int> father, rank, size;
};
class Tree {
public:
Tree(const int V = 0, const int root = 0) {
this->V = V;
this->root = root;
G = vector< vector<int> >(V, vector<int>());
}
int Size() const {
return V;
}
vector<int> &Adjacent(const int x) {
return G[x];
}
void AddEdge(const int x, const int y) {
G[x].push_back(y);
G[y].push_back(x);
}
vector<int> ComputeLCA(const vector< pair<int, int> > &queries) {
vector< vector< pair<int, int> > > nodeQueries = vector< vector< pair<int, int> > >(V, vector< pair<int, int> >());
for (int i = 0; i < int(queries.size()); ++i) {
nodeQueries[queries[i].first].push_back(make_pair(queries[i].second, i));
nodeQueries[queries[i].second].push_back(make_pair(queries[i].first, i));
}
vector<int> answers = vector<int>(int(queries.size()), NIL);
DisjointSets sets = DisjointSets(V);
vector<int> ancestors = vector<int>(V, NIL);
vector<bool> visited = vector<bool>(V, false);
AncestorDFS(root, visited, nodeQueries, sets, ancestors, answers);
return answers;
}
private:
static const int NIL = -1;
int V, root;
vector< vector<int> > G;
void AncestorDFS(const int x, vector<bool> &visited, const vector< vector< pair<int, int> > > &queries, DisjointSets &sets, vector<int> &ancestors, vector<int> &answers) {
visited[x] = true;
for (const auto &y: G[x]) {
if (!visited[y]) {
AncestorDFS(y, visited, queries, sets, ancestors, answers);
sets.Merge(x, y);
ancestors[sets.Find(x)] = x;
}
}
for (const auto &q: queries[x])
if (visited[q.first])
answers[q.second] = ancestors[sets.Find(q.first)];
}
};
Tree T;
vector< pair<int, int> > Queries;
vector<int> LCA;
void Solve() {
LCA = T.ComputeLCA(Queries);
}
void Read() {
ifstream cin("lca.in");
int v, q;
cin >> v >> q;
T = Tree(v, 0);
for (int x = 2; x <= v; ++x) {
int y;
cin >> y;
T.AddEdge(x - 1, y - 1);
}
Queries = vector< pair<int, int> >(q);
for (int i = 0; i < q; ++i) {
cin >> Queries[i].first >> Queries[i].second;
--Queries[i].first;
--Queries[i].second;
}
cin.close();
}
void Print() {
ofstream cout("lca.out");
for (int i = 0; i < int(LCA.size()); ++i)
cout << LCA[i] + 1 << "\n";
cout.close();
}
int main() {
Read();
Solve();
Print();
return 0;
}