Pagini recente » Cod sursa (job #1726582) | Cod sursa (job #971738) | Cod sursa (job #2470353) | Cod sursa (job #766666) | Cod sursa (job #996004)
Cod sursa(job #996004)
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
const int NIL = -1;
class DisjointSets {
public:
DisjointSets(const int size = 0) {
this->size = size;
father = vector<int>(size, NIL);
rank = vector<int>(size, 0);
}
int Find(const int x) {
if (father[x] == NIL)
return x;
return father[x] = Find(father[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);
return true;
}
private:
int size;
vector<int> father, rank;
};
vector< vector<int> > G;
int V, Q;
vector< vector< pair<int, int> > > Queries;
DisjointSets Sets;
vector<int> Ancestors, LCA;
vector<bool> Visited;
void DFS(const int x) {
Visited[x] = true;
Ancestors[x] = x;
for (const auto &y: G[x]) {
if (!Visited[y]) {
DFS(y);
Sets.Merge(x, y);
Ancestors[Sets.Find(x)] = x;
}
}
for (const auto &q: Queries[x])
if (Visited[q.first])
LCA[q.second] = Ancestors[Sets.Find(q.first)];
}
void Solve() {
Sets = DisjointSets(V);
Visited = vector<bool>(V, false);
Ancestors = vector<int>(V, NIL);
DFS(0);
}
inline void AddEdge(const int x, const int y) {
G[x].push_back(y);
G[y].push_back(x);
}
void Read() {
ifstream cin("lca.in");
cin >> V >> Q;
G = vector< vector<int> >(V, vector<int>());
for (int x = 2; x <= V; ++x) {
int y;
cin >> y;
AddEdge(x - 1, y - 1);
}
Queries = vector< vector< pair<int, int> > >(Q, vector< pair<int, int> >());
LCA = vector<int>(Q, NIL);
for (int i = 0; i < Q; ++i) {
int x, y;
cin >> x >> y;
--x;
--y;
Queries[x].push_back(make_pair(y, i));
Queries[y].push_back(make_pair(x, i));
}
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;
}