Cod sursa(job #67654)

Utilizator astronomyAirinei Adrian astronomy Data 25 iunie 2007 13:04:55
Problema Obiective Scor 55
Compilator cpp Status done
Runda preONI 2007, Runda Finala, Clasele 11-12 Marime 2.7 kb
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

#define MAX_N 32100
#define MAX_M 65000
#define pb push_back

int N, K, M, T, P;
vector<int> G[MAX_N], Gt[MAX_N], GC[MAX_N], GCt[MAX_N];
char viz[MAX_N];

int cnt, list[MAX_N], cc[MAX_N], D[MAX_N], DIST;
int edge[MAX_M][2];

int Q[MAX_N], Aux[MAX_N], sol[1<<17];

vector<int> R[MAX_N], IND[MAX_N];

void dfs(int x)
{
    int i;

    for(i = 0; i < G[x].size(); i++)
     if(!viz[ G[x][i] ])
        viz[ G[x][i] ] = 1, dfs(G[x][i]);

    list[++cnt] = x;
}

void dfs_t(int x)
{
    int i;

    for(i = 0; i < Gt[x].size(); i++)
     if(!cc[ Gt[x][i] ])
        cc[ Gt[x][i] ] = K, dfs_t(Gt[x][i]);
}

void preproc(void)
{
    int i, j, k, a, b;

    for(i = 1; i <= N; i++)
     if(!viz[i])
        viz[i] = 1, dfs(i);

    for(i = cnt; i >= 1; i--)
     if(!cc[ list[i] ])
        cc[ list[i] ] = ++K, dfs_t(list[i]);

    for(i = 1; i <= M; i++)
    {
        a = edge[i][0], b = edge[i][1];
        if(cc[a] != cc[b])
            GC[ cc[a] ].pb( cc[b] ), GCt[ cc[b] ].pb( cc[a] );
    }
}

void baga(int x)
{
    int i;

    for(i = 0; i < GC[x].size(); i++)
     if(!viz[ GC[x][i] ])
        viz[ GC[x][i] ] = 1, D[GC[x][i]] = DIST,
        Q[++P] = GC[x][i], baga(GC[x][i]);
}

void ruleaza(void)
{
    int i, j, k, p, x, last;
    
    for(i = 1; i <= K; i++)
     if(R[i].size())
     {
        for(j = 1; j <= K; j++)
            viz[j] = 0;
            
        P = last = 1, Q[1] = i, DIST = 0, viz[i] = 1, D[i] = 0, baga(i);
        while(P != K)
        {
            DIST++;
            for(j = last, last = P+1, k = P; j <= k; j++)
            {
                x = Q[j];
                for(p = 0; p < GCt[x].size(); p++)
                 if(!viz[ GCt[x][p] ])
                    viz[ GCt[x][p] ] = 1, Q[++P] = GCt[x][p],
                    D[ GCt[x][p] ] = DIST, baga(GCt[x][p]);
            }
        }

        for(j = 0; j < R[i].size(); j++)
            sol[ IND[i][j] ] = D[ R[i][j] ];
     }
}

void read_and_solve(void)
{
    int i, j, k, a, b;
    
    scanf("%d %d\n", &N, &M);

    for(i = 1; i <= M; i++)
        scanf("%d %d\n", &a, &b), G[a].pb(b), Gt[b].pb(a),
        edge[i][0] = a, edge[i][1] = b;

    preproc();

    scanf("%d\n", &T);
    
    for(i = 1; i <= T; i++)
    {
        scanf("%d %d\n", &a, &b);
        R[cc[a]].pb(cc[b]), IND[cc[a]].pb(i);
    }

    ruleaza();

    for(i = 1; i <= T; i++)
        printf("%d\n", sol[i]);
}

int main(void)
{
    freopen("obiective.in", "rt", stdin);
    freopen("obiective.out", "wt", stdout);

    read_and_solve();

    return 0;
}