Cod sursa(job #1738029)

Utilizator akaprosAna Kapros akapros Data 5 august 2016 16:03:19
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.37 kb
#include <bits/stdc++.h>
#define maxN 32002
#define maxM 64002
#define maxL 17
using namespace std;
int n, m, q;
int d[maxN], scc[maxN], C[maxN], nexti, c; /// ctc
bool st[maxN]; /// ctc
int anc[maxL][maxN],  Log[maxM]; /// lca
vector < int > V[maxN], v[maxN];
bool used[maxN];
int Rmq[maxL][maxM], e, E[maxN];
void dfs_ctc(int x)
{
    int i, l = V[x].size(), depth;
    d[x] = depth = ++ nexti;
    scc[++ scc[0]] = x;
    st[x] = 1;

    for (i = 0; i < l; ++ i)
        if (d[V[x][i]] == - 1)
        {
            dfs_ctc(V[x][i]);
            d[x] = min(d[x], d[V[x][i]]);
        }

        else if (st[V[x][i]])
            d[x] = min(d[x], d[V[x][i]]);

    if (d[x] == depth)
    {
        ++ c;
        while (scc[0] > 0)
        {
            C[scc[scc[0]]] = c;
            st[scc[scc[0]]] = 0;
            if (scc[scc[0]] == x)
            {
                -- scc[0];
                break;
            }
            -- scc[0];
        }
    }
}
void read()
{
    int i;
    freopen("obiective.in", "r", stdin);
    scanf("%d %d", &n, &m);
    for (i = 1; i <= m; ++ i)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        V[x].push_back(y);
    }
}
void dfs(int x)
{
    used[x] = 1;
    int i, nod;
    Rmq[0][++ e] = x;
    E[x] = e;
    for (i = 0; i < v[x].size(); ++ i)
        if (!used[nod = v[x][i]])
        {
            dfs(nod);
            Rmq[0][++ e] = nod;
            anc[0][x] = min(anc[0][nod], anc[0][x]);
        }
}
void solve()
{
    int i, j;
    for (i = 0; i <= n; ++ i)
        d[i] = -1;
    for (i = 1; i <= n; ++ i)
        if (d[i] == -1)
            dfs_ctc(i);
    for (i = 1; i <= n; ++ i)
        C[i] = c - C[i] + 1;
    for (i = 1; i <= c; ++ i)
        anc[0][i] = i;
    for (i = 1; i <= n; ++ i)
    {
        int nod, x = C[i], y;
        for (j = 0; j < V[i].size(); ++ j)
        {
            y = C[nod = V[i][j]];
            if (x == y)
                continue;
            v[x].push_back(y);
            anc[0][y] = min(anc[0][y], x);
        }
    }
    /*for (i = 1; i <= c; ++ i)
        if (anc[0][i] == c + 1)
        {
            anc[0][i] = 0;
            dfs(i);
        }*/
    dfs(1);
    for (i = 2; i <= 2 * c; ++ i)
        Log[i] = Log[i / 2] + 1;
    for (j = 1; j < Log[e]; ++ j)
        for (i = 1; i <= n; ++ i)
            anc[j][i] = anc[j - 1][anc[j - 1][i]];
    for (int i = 1; i <= Log[e]; ++i)
        for (int j = 1; j <= e - (1 << i) + 1; ++j)
            Rmq[i][j] = min(Rmq[i - 1][j], Rmq[i - 1][j + (1 << (i - 1))]);

}
int Lca(int x, int y)
{
    x = E[x];
    y = E[y];
    if (x > y)
        swap(x, y);
    int k = Log[y - x];
    return min(Rmq[k][x], Rmq[k][y - (1 << k) + 1]);
}
int Ans(int x, int l)
{
    int i, ans = 0;
    for (i = Log[c]; i >= 0; -- i)
        if (anc[i][x] > l)
        {
            x = anc[i][x];
            ans += 1 << i;
        }
    return ans + 1;
}
void write()
{
    freopen("obiective.out", "w", stdout);
    scanf("%d", &q);
    while (q --)
    {
        int x, y;
        scanf("%d %d", &x, &y);
        x = C[x];
        y = C[y];
        int l = Lca(x, y);
        if (x == l || x == y)
            printf("%d\n", 0);
        else
            printf("%d\n", Ans(x, l));
    }
}
int main()
{
    read();
    solve();
    write();
    return 0;
}