Cod sursa(job #2679875)

Utilizator Catalina07Encea Catalina Catalina07 Data 1 decembrie 2020 18:53:29
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.21 kb
#include <iostream>
#include "algo.h"
 
int getAllParents(int &node, int *parent) {
    if (node == parent[node])
        return parent[node];
    if (node != parent[node]){
        parent[node] = findParent(parent[node], parent);
        return parent[node];
    }
}
 
void sameGroup (int &node1, int &node2, int *parent, int *rank) {
    int root1 = getAllParents(node1, parent);
    int root2 = getAllParents(node2, parent);
 
    if (root1 != root2) {
        if (rank[root1] < rank[root2]){
            root1 = root1 ^ root2;
            root2 = root1 ^ root2;
            root1 = root1 ^ root2;

        }
 
        parent[root2] = root1;
        if (rank[root1] == rank[root2])
            rank[root1]++;
    }
}
 
void recursiveDfs(int &node, std::vector<std::vector<int>> &graph,
    std::vector< std::vector< std::pair<int, int> > >& queries, bool *visited,
    int *ancestor, int *parent, int *rank, std::vector<int> &answer) {
 
    parent[node] = node;
    ancestor[node] = node;
    rank[node] = 1;
    visited[node] = 1;
 
    for (int i = 0; i < graph[node].size(); ++i) {
 
        if (!visited[graph[node][i]]) {
 
            recursiveDfs(graph[node][i], graph, queries, visited,
                ancestor, parent, rank, answer);
 
            sameGroup(node, graph[node][i], parent, rank);
            ancestor[getAllParents(node, parent)] = node;
        }
    }
 
    for (int i = 0; i < queries[node].size(); ++i) {
        if (visited[queries[node][i].first] == 1)
            answer[queries[node][i].second] =
        ancestor[getAllParents(queries[node][i].first, parent)];
    }
    
}
 
std::vector<int> lca(std::vector<std::vector<int>> &graph,
    std::vector< std::pair<int, int> > &queries) {
 
    bool *visited;
    int*ancestor, *rank, *parent;
    std::vector<int> answer(queries.size(), 0);
    
    std::vector< std::vector< std::pair<int, int> > > eachNodeQuery(graph.size());
 
    for (int i = 0; i < queries.size(); ++i) {
        eachNodeQuery[queries[i].first].push_back({queries[i].second, i});
        eachNodeQuery[queries[i].second].push_back({queries[i].first, i});
 
    }
 
    visited = new bool[graph.size()] {0};
    ancestor = new int[graph.size()] {0};
    parent = new int[graph.size()] {0};
    rank = new int[graph.size()] {1};
 
    recursiveDfs(1, graph, eachNodeQuery, visited, ancestor, parent, rank, answer);
 
    delete [] visited;
    delete [] ancestor;
    delete [] rank;
    delete [] parent;
 
    return answer;
}
int main () {
    std::ifstream fin("lca.in");
    std::ofstream fout("lca.out");
 
    int n, m, node1, node2;
    std::vector< std::vector<int> > graph;
    std::vector< std::pair<int, int> > queries;
 
 
    fin >> n >> m; // number of nodes and queries
    graph.resize(n + 1);
 
    for (int i = 2; i <= n; ++i) {
        fin >> node1;
        graph[node1].push_back(i);
        graph[i].push_back(node1);
 
        // fin >> node1 >> node2;
  //       graph[node1].push_back(node2);
  //       graph[node2].push_back(node1);
    }
 
    for (int i = 0; i < m; ++i) {
        fin >> node1 >> node2;
        queries.push_back({node1, node2});
    }
 
    std::vector<int> ans = lca(graph, queries);
 
    for (int i = 0; i < ans.size(); ++i) {
        fout << ans[i] << "\n";
    }
 
    return 0;
}