Cod sursa(job #996005)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 10 septembrie 2013 18:09:38
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.3 kb
#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> > >(V, 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;
}