Pagini recente » Cod sursa (job #944) | Cod sursa (job #2835948) | Cod sursa (job #2099244) | Cod sursa (job #862569) | Cod sursa (job #931845)
Cod sursa(job #931845)
#include <fstream>
#include <stack>
#include <vector>
#include <utility>
#define mp make_pair
using namespace std;
vector < pair<int, int> > v[32010];
vector <int>G[32010], GT[32010], Nodes[32010];
int Euler[800010], rmq[800010][20], Log[800010], Depth[32010], First[32010], Nod[800010], Sum[32010], ctc[32010];
int t, n, m, i, x, y, k, comp, c, j, a, b, lca, d1, d2;
bool viz[32010];
stack <int> S;
void Liniarizare(int x, int level)
{
vector<pair<int, int> > :: iterator it;
Euler[++k] = level;
Depth[x] = level;
First[x] = k;
Nod[k] = x;
for(it = v[x].begin(); it != v[x].end(); ++it)
if(!First[it->first])
{
Sum[it->first] = Sum[x];
if(it->second) Sum[it->first]++;
Liniarizare(it->first, level+1);
Euler[++k] = level;
Nod[k] = x;
}
}
void DF_back(int x)
{
vector<int>::iterator it;
Nodes[comp].push_back(x);
ctc[x] = comp;
for(it = GT[x].begin(); it != GT[x].end(); ++it)
if(!ctc[*it]) DF_back(*it);
}
void DF(int x)
{
vector<int>::iterator it;
viz[x] = 1;
for(it = G[x].begin(); it != G[x].end(); ++it)
if(!viz[*it]) DF(*it);
S.push(x);
}
int main()
{
vector <int> :: iterator it, vec;
ifstream fi("obiective.in");
ofstream fo("obiective.out");
fi >> n >> m;
for(i = 1; i <= m; i++)
{
fi >> x >> y;
G[x].push_back(y);
GT[y].push_back(x);
}
for(i = 1; i <= n; i++) if(!viz[i]) DF(i);
while(!S.empty())
{
while(!S.empty() and ctc[S.top()]) S.pop();
if(S.empty()) break;
comp++;
DF_back(S.top());
}
for(i = 1; i <= comp; i++)
for(it = Nodes[i].begin(); it != Nodes[i].end(); ++it)
{
for(vec = G[*it].begin(); vec != G[*it].end(); ++vec)
if(ctc[*vec] != i) v[i].push_back(mp(ctc[*vec], 0));
for(vec = GT[*it].begin(); vec != GT[*it].end(); ++vec)
if(ctc[*vec] != i) v[i].push_back(mp(ctc[*vec], 1));
}
Liniarizare(1, 1);
for(i = 2; i <= k; i++) Log[i] = Log[i/2] + 1;
for(i = 1; i <= k; i++) rmq[i][0] = i;
for(c = 1; (1<<c) <= k; c++)
{
for(i = 1; i <= k; i++)
{
rmq[i][c] = rmq[i][c-1];
j = i + (1<<(c-1));
if(j <= k and Euler[rmq[j][c-1]] < Euler[rmq[i][c]]) rmq[i][c] = rmq[j][c-1];
}
}
fi >> t;
while(t--)
{
fi >> a >> b;
a = ctc[a]; b = ctc[b];
x = First[a]; y = First[b];
if(x > y) swap(x, y);
c = Log[y - x + 1];
lca = rmq[x][c];
j = y - (1<<c) + 1;
if(Euler[lca] > Euler[rmq[j][c]]) lca = rmq[j][c];
lca = Nod[lca];
d1 = Depth[a] - Depth[lca] - (Sum[a] - Sum[lca]);
d2 = Sum[b] - Sum[lca];
fo << d1 + d2 << "\n";
}
return 0;
}