Cod sursa(job #2500146)

Utilizator 1chiriacOctavian Neculau 1chiriac Data 27 noiembrie 2019 12:13:02
Problema Obiective Scor 5
Compilator cpp-64 Status done
Runda guritza Marime 3.42 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
int n,m,nod,conexe[32003],kontor,viz[32003],t,cost[32003];pair <int,int> unu,doi;
vector <int> graf[32003];vector <int> grafinv[32003];vector <pair <int,int> > grafn[32003];vector <int> tarec[32003];
vector <int> stiva;queue <int> chestie;
void dfs (int nod1) {
	viz[nod1]=1;
	for(int i=0;i<(int)graf[nod1].size();++i)
		if(viz[graf[nod1][i]]==0)
			dfs(graf[nod1][i]);
	stiva.push_back(nod1);
}
void dfs1 (int nod1) {
	viz[nod1]=0;conexe[nod1]=kontor;tarec[kontor].push_back(nod1);
	for(int i=0;i<(int)grafinv[nod1].size();++i)
		if(viz[grafinv[nod1][i]]==1)
			dfs1(grafinv[nod1][i]);
}
void ctc_kosaraju () {
	for(int i=1;i<=n;++i)
		if(viz[i]==0) 
			dfs(i);
	while(stiva.size()!=0) {
		nod=stiva[stiva.size()-1];stiva.pop_back();
		if(viz[nod]==1)
			++kontor,dfs1(nod);
	}
}
void dfs2 (int nod1) {
	viz[nod1]=1;
	for(int i=0;i<(int)graf[nod1].size();++i)
		if(conexe[nod1]!=conexe[graf[nod1][i]]) {
			grafn[conexe[nod1]].push_back(make_pair(conexe[graf[nod1][i]],1));
			grafn[conexe[graf[nod1][i]]].push_back(make_pair(conexe[nod1],2));
			dfs2(graf[nod1][i]);
		}
}
void fa_graf () {
	// in grafn faci graf aciclic neorientat;
	bool ok;
	for(int i=1;i<=n;++i)
		for(int j=0;j<(int)graf[i].size();++j) {
			if(conexe[i]!=conexe[graf[i][j]]) {
				ok=true;
				unu=make_pair(conexe[graf[i][j]],1);
				for(int i2=0;i2<(int)grafn[conexe[i]].size();++i2)
					if(grafn[conexe[i]][i2]==unu) {
						ok=false;
						break;
					}
				if(ok==true) {
					grafn[conexe[i]].push_back(unu);
					grafn[conexe[graf[i][j]]].push_back(make_pair(conexe[i],2));
				}
			}
		}
}
void dfs3 (int nod1) {
	viz[nod1]=1;
	for(int i=0;i<(int)grafn[nod1].size();++i)
		if(viz[grafn[nod1][i].first]==0 && grafn[nod1][i].second==1)
			dfs3(grafn[nod1][i].first);
}
void bfs () {
	cost[chestie.front()]=1;
	while(chestie.size()!=0) {
		nod=chestie.front();
		for(int i=0;i<(int)grafn[nod].size();++i)
			if(grafn[nod][i].second==2 && cost[grafn[nod][i].first]==0) {
				cost[grafn[nod][i].first]=cost[nod]+1;
				chestie.push(grafn[nod][i].first);
			}
		chestie.pop();
	}
}
int main () {
	int nr1,nr2;bool ok;
	freopen("obiective.in","r",stdin);
	freopen("obiective.out","w",stdout);
	//tari conexe;
	//daca sunt in aceeasi componenta=> 0, daca nu trebuie unite compenentele;
	scanf("%d%d", &n, &m);
	for(int i=1;i<=m;++i) {
		scanf("%d%d", &nr1, &nr2);
		graf[nr1].push_back(nr2);
		grafinv[nr2].push_back(nr1);
	}
	ctc_kosaraju();
	fa_graf();
	/*for(int i=1;i<=n;++i) {
		for(int j=0;j<(int)grafn[i].size();++j)
			printf("%d ", grafn[i][j].first);
		printf("\n");
	}*/
	scanf("%d", &t);++t;
	while(--t) {
		scanf("%d%d", &nr1, &nr2);
		nr1=conexe[nr1];nr2=conexe[nr2];
		if(nr1==nr2)
			printf("0\n");
		else {
			ok=false;
			for(int i=0;i<(int)grafn[nr1].size();++i)
				if(grafn[nr1][i].first==nr2) {
					if(grafn[nr1][i].second==1) {
						printf("0\n");ok=true;
						break;
					 }
					 else {
						 printf("1\n");ok=true;
						 break;
					 }
				}
			if(ok==false) {
				//am belit pl;
				memset(viz,0,sizeof(viz));
				dfs3(nr1);
				//faci un dfs doar pe muchiile cu 1;daca nu merge nici asa faci bfs pe muchiile cu 2; 
				if(viz[nr2]==1)
					printf("0\n");
				else {
					chestie.push(nr1);
					memset(cost,0,sizeof(cost));
					bfs();
					printf("%d\n", cost[nr2]-1);
				}
			}
		}
	}
	return 0;
	//daca au un punct comun, nr=1 sau 0,daca nu au niciun punct comun faci dfs;
}