Pagini recente » Cod sursa (job #1935549) | Cod sursa (job #746646) | Cod sursa (job #899259) | Cod sursa (job #390259) | Cod sursa (job #1182485)
#include<stdio.h>
#include<stack>
#include<vector>
#include<algorithm>
const int N=33000;
using namespace std;
FILE *f,*g;
stack<int> varfuri;
int n, m, q, index, root;
vector<int> graph[N], gdag[N], gdags[N];
bool viz[N], seen[N];
int deg[N]; int depth[N], updepth[N], comp[N];
int adanc[N], low[N], tata[N];
void Read(void){
f=fopen("obiective.in","r");
g=fopen("obiective.out","w");
fscanf(f,"%d%d",&n,&m);
int a,b;
for(int i=1;i<=m;i++){
fscanf(f,"%d%d",&a,&b);
graph[a].push_back(b);
}
fscanf(f,"%d",&q);
}
//Auxiliara MakeDAG
void DFSDAG(int v){
vector<int>::iterator it=graph[v].begin(); int aux;
seen[v]=1; updepth[v]=depth[v]; varfuri.push(v);
while(it != graph[v].end()){
if ( !seen[*it]){
depth[*it]=depth[v]+1;
DFSDAG(*it);
if (updepth[*it] >= depth[*it]) {
comp[*it]=++index;;
while (varfuri.top() != *it) {
aux=varfuri.top(); varfuri.pop();
comp[aux]=index;
}
varfuri.pop();
}
else if (updepth[*it] < updepth[v]) updepth[v]=updepth[*it];
}
else if (updepth[*it] < updepth[v]) updepth[v]=updepth[*it];
it++;
}
}
//creeaza DAG
void MakeDAG(void){
int i; int aux;
for(i=1;i<=n;i++){
if (!seen[i]){
DFSDAG(i); if (!varfuri.empty()) index++;
while (!varfuri.empty()){
aux=varfuri.top(); varfuri.pop();
comp[aux]=index;
}
}
}
vector<int>::iterator it;
for(i=1; i<=n; i++) {
it=graph[i].begin();
while(it !=graph[i].end()){
if (comp[*it] != comp[i]) {
gdag[comp[i]].push_back(comp[*it]); gdags[comp[*it]].push_back(comp[i]);
deg[comp[*it]]++;
}
it++;
}
}
n=index;
}
//Gaseste radacina DAG (exsitenta && unica din ipoteza)
void FindRoot(void){
for(root=1;root<=n;root++) if (deg[root] == 0) return;
}
//Creeaza arborele de care ne folosim
void MakeArb(int v){
vector<int>::iterator it=gdag[v].begin(), itaux; viz[v]=1; low[v]=tata[v];
while (it != gdag[v].end()){
if (!viz[*it]){
adanc[*it]=adanc[v]+1; tata[*it]=v;
MakeArb(*it);
if (adanc[low[*it]] < adanc[low[v]]) low[v]=low[*it];
}
else if (adanc[low[*it]] < adanc[low[v]]) low[v]=low[*it];
it++;
}
itaux=gdags[v].begin();
while (itaux != gdags[v].end()){
if (adanc[*itaux] < adanc[low[v]]) low[v]=*itaux;
itaux++;
}
}
int Stramos(int v, int pasi){
while(pasi){
v=tata[v];
pasi--;
}
return v;
}
int FindLCA(int v, int u){
if (adanc[v] < adanc[u]) swap(u,v);
v=Stramos(v,adanc[v]-adanc[u]);
if (u == v) return adanc[u];
while (u != v){
u=tata[u], v=tata[v];
}
return adanc[u];
}
int FindMin(int v, int u){
int deep=FindLCA(v,u);
int cnt=0;
while (deep < adanc[v]){
v=low[v], cnt++;
}
return cnt;
}
void Solve(void){
int a,b;
for(int i=1;i<=q;i++){
fscanf(f,"%d%d",&a,&b);
fprintf(g,"%d\n",FindMin(comp[a],comp[b]));
}
}
int main(void){
Read();
MakeDAG(); FindRoot(); tata[root]=root; MakeArb(root);
Solve();
return 0;
}