Cod sursa(job #69267)

Utilizator mariusdrgdragus marius mariusdrg Data 2 iulie 2007 12:29:01
Problema Obiective Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 4 kb
#include<stdio.h>
#include<algorithm>
#define vi vector <int>
#define vii vector <int> :: iterator
#define pb push_back
#include<vector>

using namespace std;

const int maxn = 32000;
const int maxn2 = 17;

int i;
int x;
int y;
int st[maxn];
int j;
int c[maxn];
int nrc;
int poz[maxn];
vi vect[maxn];
vi vectinv[maxn],vectc[maxn];
int n;
int m[maxn2][maxn];
int used[maxn];


inline int max(int i,int j)
{
        return i > j ? i : j;
}

int querry(int st,int end)
{
        int min = 0;
        int p;
        for(p = 1,j = 0;p <= end - st; ++j,p <<= 1);
        for(;p;p >>= 1,j--)
        {
                if (st + p  - 1<= end)
                {
                        min = max(m[j][st],min);
                        st += p - 1;
                }
        }
       return min;
}

void dfs(int i)
{
        if (used[i]) return;
        used[i] = 1;
        vii it;
        for(it = vect[i].begin();it != vect[i].end(); ++it)
        {
                dfs(*it);
        }
        st[++st[0]] = i;
}

void dfsc(int i)
{
        if (used[i]) return;
        used[i] = 1;
        vii it;
        for(it = vectc[i].begin();it != vectc[i].end(); ++it)
        {
                dfsc(*it);
        }
        st[++st[0]] = i;
        poz[i] = st[0];
}


void dfsinv(int i)
{
        if (used[i]) return;
        used[i] = 1;
        c[i] = nrc;
        vii it;
        for(it = vectinv[i].begin();it != vectinv[i].end(); ++it)
        {
                dfsinv(*it);
        }
        
}

int main()
{

        freopen("obiective.in","r",stdin);
        freopen("obiective.out","w",stdout);
        int mu;

        scanf("%d %d",&n,&mu);
        for(i = 1;i <= mu; ++i)
        {
                scanf("%d %d",&x,&y);
                vect[x].pb(y);
                vectinv[y].pb(x);
        }
        for(i = 1;i <= n; ++i)
        {
                if (!used[i])
                {
                        dfs(i);
                }
        }
        memset(used,0,sizeof(used));
        for(;st[0]; --st[0])
        {
                if (!used[st[st[0]]])
                {
                        nrc++;
                        dfsinv(st[st[0]]);
                }
        }
        for(i = 1;i <= st[0]; ++i)
        {
                poz[st[i]] = i;
        }
        for(i = 1;i <= nrc; ++i)
        {
                m[0][i] = poz[i];
        }
        for(i = 1;i <= n; ++i)
        {
                vii it;
                for(it = vect[i].begin(); it != vect[i].end(); ++it)
                {
                        vectc[c[i]].pb(c[*it]);
                }
        }
        for(i = 1;i <= n; ++i)
        {
                sort(vectc[i].begin(),vectc[i].end());
                vectc[i].resize(unique(vectc[i].begin(),vectc[i].end()) - vectc[i].begin());
        }
        memset(used,0,sizeof(used));
        memset(st,0,sizeof(st));
        for(i = 1;i <= nrc; ++i)
        {
                if (!used[i]) dfsc(1);
        }
        for(i = 1;i <= n; ++i)
        {
                vii it;
                for(it = vectinv[i].begin(); it != vectinv[i].end(); ++it)
                {
                        m[0][poz[c[i]]] = max(m[0][poz[c[i]]],poz[c[*it]]);
                }
       
        }
        int p;
        for(p = 1,j = 1;p <= nrc; p <<= 1, ++j)
        {
                for(i = 1;i <= nrc; ++i)
                {
                        m[j][i] = max(m[j - 1][i],m[j - 1][i + p]);
                }
        }
        int q;
        scanf("%d",&q);
        int ma;
        for(i = 1;i <= q; ++i)
        {
                scanf("%d %d",&y,&x);
                int sol = 0;
                y = c[y];
                x = c[x];
                ma = poz[y];
                while(ma < poz[x])
                {
                        ma = querry(poz[y],ma);
                        sol++;
                }
                printf("%d\n",sol);
        }

        return 0;
        
}