Pagini recente » Cod sursa (job #475471) | Cod sursa (job #933681) | Cod sursa (job #571470) | Cod sursa (job #3243219) | Cod sursa (job #3327476)
#include <bits/stdc++.h>
#define NMAX 32002
#define LOGMAX 16
using namespace std;
ifstream fin("obiective.in");
ofstream fout("obiective.out");
int N,M,Q;
vector <int> G[NMAX],Gt[NMAX];
vector <int> S;
vector <int> Gctc[NMAX];
int ctc[NMAX];
char vis[NMAX];
int sparse[NMAX][LOGMAX + 2];
int sparse2[NMAX][LOGMAX + 2];
int depth[NMAX];
int T[NMAX];
void sort_top(int node)
{
vis[node] = 1;
for(int x : G[node]){
if(!vis[x]) sort_top(x);
}
S.push_back(node);
}
void dfs1(int node,vector <int> *G,int cnt)
{
ctc[node] = cnt;
for(int x : G[node]){
if(ctc[x] == 0) dfs1(x,G,cnt);
}
return;
}
void dfs2(int node, vector <int> *G)
{
vis[node] = 1;
for(int x : G[node]){
if(depth[sparse[x][0]] > depth[node]){
sparse[x][0] = node;
}
if(!vis[x]){
depth[x] = depth[node] + 1;
T[x] = node;
dfs2(x,G);
}
}
return;
}
void dfs3(int node, vector <int> *G)
{
sparse2[node][0] = T[node];
for(int x : G[node]){
if(T[x] == node) dfs3(x,G);
}
if(depth[sparse[T[node]][0]] > depth[sparse[node][0]]){
sparse[T[node]][0] = sparse[node][0];
}
}
int move_up(int node,int steps, int sparse[NMAX][LOGMAX + 2])
{///nu vr sa fac optimizare sa am doar log si nu log^2
int lg =0;
while(steps){
if(steps&1){
node = sparse[node][lg];
}
steps >>=1;
lg++;
}
return node;
}
int __lca(int a,int b)
{
///aducem la acceasi adancime
if(depth[a] > depth[b]){///presupunem ca b ii mai adanc
swap(a,b);
}
b = move_up(b,depth[b] - depth[a], sparse2);
int le,ri,ret;
le = 0;
ri = N;
ret = N;
while(le <= ri){///log^2
int mid = (le+ri)/2;
int aa = move_up(a,mid,sparse2);
int ba = move_up(b,mid,sparse2);
if(aa == ba){
ret = aa;
ri = mid-1;
}else{
le = mid+1;
}
}
return ret;
}
int main()
{
fin >> N >> M;
for(int i=1;i<=M;i++){
int x,y;
fin >> x >> y;
G[x].push_back(y);
Gt[y].push_back(x);
}
for(int i=1;i<=N;i++){
if(!vis[i]) sort_top(i);
}
reverse(S.begin(),S.end());
int cnt = 0;
for(int node : S){
if(ctc[node] == 0) dfs1(node,Gt,++cnt);
}
for(int node=1;node<=N;node++){
for(int x: G[node]){
if(ctc[x] != ctc[node]){
Gctc[ctc[node]].push_back(ctc[x]);
}
}
}
memset(vis,0,sizeof(vis));
depth[0] = INT_MAX;
dfs2(1, Gctc);
sparse[1][0] = 1;
dfs3(1, Gctc);
for(int lg = 1;lg <LOGMAX;lg++){
for(int node = N;node >=1;node--){
sparse[node][lg] = sparse[sparse[node][lg-1]][lg-1];
sparse2[node][lg] = sparse2[sparse2[node][lg-1]][lg-1];
}
}
fin >> Q;
while(Q--){
int g,m;
fin >> g >> m;
int a = ctc[g];
int b = ctc[m];
int lca = __lca(a,b);
int le = 0;
int ri = N;
int ans = N;
while(le <= ri){
int mid = (le+ri)/2;
int x = move_up(a,mid,sparse);
if(depth[x] <= depth[lca]){
ans = mid;
ri = mid - 1;
}else{
le = mid +1;
}
}
fout << ans << "\n";
}
}