Pagini recente » Cod sursa (job #3169755) | Cod sursa (job #589359) | Cod sursa (job #2339652) | Cod sursa (job #3207713) | Cod sursa (job #923436)
Cod sursa(job #923436)
#include <stdio.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define Nmax 32005
#define inf 100000
vector < vector<int> > graf, grafT;
int n, m, c, nrctc, t, s, d;
int visited[Nmax], forder[Nmax], ctc[Nmax], dist[Nmax];
void read(){
int x, y;
scanf("%i %i", &n, &m);
graf.resize(n+1);
grafT.resize(n+1);
for(int i = 1; i <= m; ++i){
scanf("%i %i", &x, &y);
graf[x].push_back(y);
grafT[y].push_back(x);
}
}
int findD(int x, vector<int>& v){ // verific daca elementul x se afla in vectorul v
int size = v.size(), i;
for(i = 0; i < size; ++i)
if(v[i] == x) return 1;
return 0;
}
void dfsO(int v){ // stabilesc timpii terminali de cautare pentru dfs in graful initial
int i, size;
visited[v] = 1;
for(i = 0, size = graf[v].size(); i < size; ++i)
if(!visited[ graf[v][i] ])
dfsO(graf[v][i]);
forder[++c] = v;
}
void dfsT(int v){ // parcurg graful transpus pentru a gasi componentele tare conexe (kosaraju)
int i, size;
visited[v] = 0;
ctc[v] = nrctc;
for(i = 0, size = grafT[v].size(); i < size; ++i)
if(visited[ grafT[v][i] ])
dfsT( grafT[v][i] );
}
void bellman(){
int at, size;
queue<int> q;
visited[s] = 1;
dist[s] = 0;
q.push(s);
while(!q.empty()){
at = q.front();
q.pop();
size = grafT[at].size();
visited[at] = 0;
for(int i = 0; i < size; ++i){
if(grafT[at][i] < 0){ // muchie de la gratT[at][i] la at
if(dist[ -grafT[at][i] ] > dist[at] + 1){
dist[ -grafT[at][i] ] = dist[at] + 1;
if(!visited[ -grafT[at][i] ]){
visited[ -grafT[at][i] ] = 1;
q.push( -grafT[at][i]);
}
}
}
else{ // muchie de la at la grafT[at][i]
if(dist[ grafT[at][i] ] > dist[at]){
dist[ grafT[at][i] ] = dist[at];
if(!visited[ grafT[at][i] ]){
visited[ grafT[at][i] ] = 1;
q.push(grafT[at][i]);
}
}
}
}
}
}
void solve(){
for(int i = 1; i <= n ; ++i) // kosaraju
if(!visited[i])
dfsO(i);
for(int i = n; i >= 1; --i) // kosaraju
if(visited[ forder[i] ]){
++nrctc;
dfsT(forder[i]);
}
for(int i = 1; i <= n; ++i) grafT[i].clear(); // reseteaza grafT
for(int i = 1; i <= n; ++i) // grafT este graful componentelor conexe
for(int j = 0, size = graf[i].size(); j < size; ++j)
if(ctc[i] != ctc[ graf[i][j] ]){
if(!findD(ctc[ graf[i][j] ], grafT[ ctc[i] ])) // verific daca am mai adaugat aceeasi muchie, in caz contrar o adaug
grafT[ ctc[i] ].push_back( ctc[ graf[i][j] ] );
if(!findD(-ctc[i], grafT[ ctc[ graf[i][j] ] ]))
grafT[ ctc[ graf[i][j] ] ].push_back( -ctc[i] ); // daca vecinul este cu minus, muchia este de la vecin la nod
}
scanf("%i", &t);
for(int ii = 1; ii <= t; ++ii){
scanf("%i %i", &s, &d);
s = ctc[s];
d = ctc[d];
for(int i = 1; i <= nrctc; ++i) visited[i] = 0;
for(int i = 1; i <= nrctc; ++i) dist[i] = inf;
bellman();
printf("%i\n", dist[d]);
}
}
int main(){
freopen("obiective.in", "r", stdin);
freopen("obiective.out", "w", stdout);
read();
solve();
fclose(stdout);
return 0;
}