Cod sursa(job #2679500)

Utilizator Catalina07Encea Catalina Catalina07 Data 30 noiembrie 2020 17:47:26
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.76 kb
#include <bits/stdc++.h>
 
#define N 100000
#define MAXLEVEL 100 
  
void dfs(int currentNode, int prevNode, std::vector<int>& depth,
         std::vector<std::vector<int>>& parent, const std::vector<std::vector<int>>& graph) {   
    parent[currentNode][0] = prevNode; 
    depth[currentNode] = depth[prevNode] + 1;
 
    for (int i = 0; i < graph[currentNode].size(); i++) { 
        if (graph[currentNode][i] != prevNode) {
            dfs(graph[currentNode][i], currentNode, depth, parent, graph); 
        } 
    } 
} 
  
void findParent(int n, std::vector<std::vector<int>>& parent) {  
int lvl, i; 
    for (lvl = 1; lvl < MAXLEVEL; lvl++) { 
        for (int i = 1; i <= n; i++) { 
            if (parent[i][lvl-1] != -1) {
                parent[i][lvl] = parent[parent[i][lvl-1]][lvl-1]; 
            } 
        } 
    } 
} 
 
std::vector<int> lca(const std::vector<std::vector<int>>& graph, const std::vector< std::pair<int, int> >& queries) {
    std::vector<int> depth(graph.size(), 0);
    std::vector<std::vector<int>> parent(graph.size() + 1);
 
    for(auto& p:parent) {
        p.resize(MAXLEVEL, -1);
    } 
    dfs(1, 0, depth, parent, graph);

    findParent(graph.size(), parent); 
 
    std::vector<int> results;
 
    for(auto query:queries) {
        int v = query.first, u = query.second;
        
        if (depth[v] < depth[u]) {
            std::swap(u, v); 
        }
    
        int h = depth[v] - depth[u]; 
        for (int i = 0; i < MAXLEVEL; i++) {
            if (h % 2 == 1) {
                v = parent[v][i]; 
            }
            h /= 2;
        } 
        if (u == v) {
            results.push_back(u);
            continue;
        }
        for (int i = MAXLEVEL -1 ; i >= 0; i--) {
            if (parent[u][i] != parent[v][i]) { 
                u = parent[u][i]; 
                v = parent[v][i]; 
            }
        } 
        results.push_back(parent[u][0]);
    }
    return results; 
} 
 
void addEdge(int a,int b, std::vector<std::vector<int>>& graph) 
{ 
    graph[a].push_back(b); 
    graph[b].push_back(a); 
} 
 
int main() 
{       
    std::ifstream inputStream;
    std::ofstream outputStream;
 
    int n, m;
    
    inputStream.open("lca.in");
 
    inputStream>>n>>m;
 
    std::vector<std::vector<int>> graph(n + 5);
    std::vector< std::pair<int, int> > queries;
    int src, dest;
 
    for(int i = 1; i < n ; ++i) {
        inputStream>>dest;
 
        addEdge(dest, i +1, graph);
    }
 
    int u , v;
 
    for(int i = 0; i < m; ++i) {
        inputStream>>u>>v;
        queries.push_back(std::make_pair(u, v));
    }
 
    std::vector<int> res = lca(graph, queries);
 
    outputStream.open("lca.out");
 
    for(auto& r:res) {
        outputStream<<r<<'\n';
    }
 
    outputStream.close();
    inputStream.close();
    
 
    return 0; 
}