Cod sursa(job #844952)

Utilizator stoicatheoFlirk Navok stoicatheo Data 30 decembrie 2012 00:27:07
Problema Obiective Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.42 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
 
#define maxn 32005
#define maxlog 17
#define pb push_back
 
using namespace std;
 
FILE*f=fopen("obiective.in","r");
FILE*g=fopen("obiective.out","w");
 
int n,m,Ncomp,R,index;
int viz[maxn],st[maxn],comp[maxn],last[maxn],gr_in[maxn],up[maxn],NIV[maxn],NIV_arb[maxn],P[maxlog][maxn],first[maxn];
vector<int>W[maxn],Wt[maxn],C[maxn],G[maxn],Gt[maxn],V[maxn];
 
inline void citire () {
 
    fscanf(f,"%d %d",&n,&m);
    int x,y;
    for ( int i = 1 ; i <= m ; ++i ){
        fscanf(f,"%d %d",&x,&y);
        W[x].pb(y); Wt[y].pb(x);
    }
}
 
void kosaraju1 ( int nod ){
     
    viz[nod] = 1;
    for ( vector<int>::iterator itt = W[nod].begin() ; itt != W[nod].end() ; ++itt ){
        int vecin = (*itt);
        if ( !viz[vecin] ){
            kosaraju1(vecin);
        }
    }
    st[++st[0]] = nod;
}
 
void kosaraju2 ( int nod ){
 
    viz[nod] = 0;
    comp[nod] = Ncomp; C[Ncomp].pb(nod);
    for ( vector<int>::iterator itt = Wt[nod].begin() ; itt != Wt[nod].end() ; ++itt ){
        int vecin = (*itt);
        if ( viz[vecin] ){
            kosaraju2(vecin);
        }
    }
}
 
inline void CTC () {
 
    for ( int i = 1 ; i <= n ; ++i ){
        if ( !viz[i] ){
            kosaraju1(i);
        }
    }
     
    for ( int i = n ; i >= 1 ; --i ){
        if ( viz[ st[i] ] ){
            ++Ncomp;
            kosaraju2(st[i]);
        }
    }
}
 
inline void build_CTC_graph () {
     
    for ( int c = 1 ; c <= Ncomp ; ++c ){
         
        last[c] = c;
        for ( vector<int>::iterator itt = C[c].begin() ; itt != C[c].end() ; ++itt ){
            int nod = (*itt);
            for ( vector<int>::iterator itt_edges = W[nod].begin() ; itt_edges != W[nod].end() ; ++itt_edges ){
                int next_comp = comp[*itt_edges];
                if ( last[next_comp] != c ){
                    last[next_comp] = c;
                    G[c].pb(next_comp); Gt[next_comp].pb(c);
                    ++gr_in[next_comp];
                }
            }
        }
         
        sort(G[c].begin(),G[c].end());
    }
}
 
inline void get_root () {
 
    n = Ncomp;
    for ( int i = 1 ; i <= n ; ++i ){
        if ( !gr_in[i] ){
            R = i;
        }
    }
}
 
void DFS ( int nod , int t ){
    NIV[nod] = NIV[t]+1; up[nod] = t;
    viz[nod] = 1; first[nod] = ++index;
     
    for ( vector<int>::iterator itt = G[nod].begin() ; itt != G[nod].end() ; ++itt ){
        int fiu = (*itt);
        if ( !viz[fiu] ){
            DFS(fiu,nod);
        }
        if ( NIV[up[fiu]] < NIV[up[nod]] ){
            up[nod] = up[fiu];
        }
    }
     
    for ( vector<int>::iterator itt = Gt[nod].begin() ; itt != Gt[nod].end() ; ++itt ){
        int stramos = (*itt);
        if ( NIV[stramos] < NIV[up[nod]] ){
            up[nod] = stramos;
        }
    }
    last[nod] = index;
}
 
void DFS_tree ( int nod , int t ){
 
    NIV_arb[nod] = NIV_arb[t] + 1;
    for ( vector<int>::iterator itt = V[nod].begin() ; itt != V[nod].end() ; ++itt ){
        DFS_tree(*itt,nod);
    }
}
 
inline void build_tree () {
 
    for ( int i = 1 ; i <= n ; ++i ){
        if ( up[i] ){
            V[up[i]].pb(i);
        }
    }
     
    DFS_tree(R,0);
     
    for ( int i = 1 ; i <= n ; ++i ){
        P[0][i] = up[i];
    }
    for ( int p = 1 ; (1<<p) <= n ; ++p ){
        for ( int i = 1 ; i <= n ; ++i ){
            P[p][i] = P[p-1][ P[p-1][i] ];
        }
    }
}
 
inline bool stramos ( int x , int y ){
    return first[x] <= first[y] && last[y] <= last[x];
}
 
inline void solve () {
     
    int q,x,y;
    fscanf(f,"%d",&q);
    for ( int i = 1 ; i <= q ; ++i ){
        fscanf(f,"%d %d",&x,&y);
        x = comp[x]; y = comp[y];
         
        int sol = 0;
        if ( !stramos(x,y) ){
             
            int firstx = x;
            for ( int p = 16 ; p >= 0 ; --p ){
                 
                if ( P[p][x] && !stramos(P[p][x],y) ){
                    x = P[p][x];
                }
            }
             
            sol = NIV_arb[firstx] - NIV_arb[x] + 1;
        }
         
        fprintf(g,"%d\n",sol);
    }
}
 
int main () {
 
    citire();
     
    CTC();
    build_CTC_graph();
     
    get_root();
    DFS(R,0);
     
    build_tree();
     
    solve();
     
    fclose(f);
    fclose(g);
     
    return 0;
}