Pagini recente » Cod sursa (job #1228550) | Cod sursa (job #1165689) | Cod sursa (job #1197189) | Cod sursa (job #1864200) | Cod sursa (job #1210150)
#include <iostream>
using namespace std;
#include <fstream>
#include <algorithm>
#include <list>
#include <vector>
namespace e_040_lca_
{
void build_tree(int N, int* parents, vector<list<int>>& tree)
{
tree.resize(N + 1);
//create the tree
for (int i = 2; i <= N; i++) {
int p = parents[i];
tree[p].push_back(i); //add the child
}
}
void dfs_euler_depth(int node, int depth, int N, vector<list<int>>& tree, int& eid, int* er, vector<vector<int>>& er_pos, int* depths)
{
depths[node] = depth;
er_pos[node].push_back(eid);
er[eid++] = node;
for (auto& child : tree[node]) {
dfs_euler_depth(child, depth + 1, N, tree, eid, er, er_pos, depths);
er_pos[node].push_back(eid);
er[eid++] = node;
}
}
int lca_search(int u, int v, vector<list<int>>& tree, int* er, int* depths)
{
if (u == v) return u;
//look for u and v in the euler representation
int f = -1;
int idf = 0, ids = 0;
int i = 0;
while (1) {
if (er[i] == u) {
if (f == v) { ids = i; break; }
else {
f = u; idf = i;
}
}
if (er[i] == v) {
if (f == u) { ids = i; break; }
else {
f = v; idf = i;
}
}
i++;
}
//int the range idf and ids find the node with the minimum depth
int id_min = idf;
for (int i = idf + 1; i <= ids; i++) {
if (depths[er[i]] < depths[er[id_min]]) id_min = i;
}
//return the lca of the nodes u and v
return er[id_min];
}
int lca(int u, int v, vector<list<int>>& tree, int* er, vector<vector<int>>& er_pos, int* depths)
{
if (u == v) return u;
//who appears first and who second
if (er_pos[u].front() > er_pos[v].front()) swap(u, v); //ensure u is the firs and v the second
int pos_v = er_pos[v].front();
unsigned int i = 1;
while (i < er_pos[u].size() && er_pos[u][i] < pos_v) i++;
int pos_u = er_pos[u][i - 1];
//int the range idf and ids find the node with the minimum depth
int id_min = pos_u;
for (int i = pos_u + 1; i <= pos_v; i++) {
if (depths[er[i]] < depths[er[id_min]]) id_min = i;
}
//return the lca of the nodes u and v
return er[id_min];
}
}
//int e_040_lca()
int main()
{
using namespace e_040_lca_;
int N, M;
ifstream ifs("lca.in");
ofstream ofs("lca.out");
ifs >> N >> M;
int* parents = new int[N + 1];
int* depths = new int[N + 1];
for (int i = 2; i <= N; i++) {
int p;
ifs >> p;
parents[i] = p;
}
vector<list<int>> tree;
build_tree(N, parents, tree);
//count the number of childs
int no_ch = 0;
for (int i = 1; i <= N; i++) {
no_ch += tree[i].size();
}
//euler representation
int* er = new int[no_ch + N];
vector<vector<int>> er_pos;
er_pos.resize(N + 1);
int eid = 0;
dfs_euler_depth(1, 0, N, tree, eid, er, er_pos, depths);
for (int i = 1; i <= M; i++) {
int u, v;
ifs >> u >> v;
ofs << lca(u, v, tree, er, er_pos, depths) << "\n";
}
ifs.close();
ofs.close();
delete[] parents; delete[] depths; delete[] er;
return 0;
}