Cod sursa(job #1738533)

Utilizator akaprosAna Kapros akapros Data 6 august 2016 22:18:50
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.34 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, f[maxN]; /// ctc
bool vis[maxN]; /// ctc
int anc[maxL][maxN],  Log[maxM]; /// lca
vector < int > V[maxN], W[maxN], v[maxN];
bool used[maxN];
int Rmq[maxL][maxM], e, E[maxN];
void dfs_ctc(int x)
{
    int i, l = V[x].size();
    for (i = 0; i < l; ++ i)
        if (!vis[V[x][i]])
        {
            vis[V[x][i]] = 1;
            dfs_ctc(V[x][i]);
        }
    f[++ f[0]] = x;
}
void DFS(int x)
{
    int i, l = W[x].size();
    for (i = 0; i < l; ++ i)
        if (!vis[W[x][i]])
        {
            vis[W[x][i]] = 1;
            C[W[x][i]] = c;
            DFS(W[x][i]);
        }
}
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);
        W[y].push_back(x);
    }
}
void dfs(int x)
{
    used[x] = 1;
    int i, nod;
    Rmq[0][++ e] = x;
    E[x] = e;
    sort(v[x].begin(), v[x].end());
    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 = 1; i <= n; ++ i)
        if (!vis[i])
        {
            vis[i] = 1;
            dfs_ctc(i);
        }
    memset(vis, 0, sizeof(vis));
    for (i = n; i >= 1; -- i)
        if (!vis[f[i]])
        {
            vis[f[i]] = 1;
            C[f[i]] = ++ c;
            DFS(f[i]);
        }
    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;
}