Pagini recente » Cod sursa (job #2440188) | Cod sursa (job #641756) | Cod sursa (job #2813859) | Cod sursa (job #2688568) | Cod sursa (job #2798552)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#define MAX 100001
using namespace std;
ifstream fin ("biconex.in");
ofstream fout("biconex.out");
vector <int> compBiconexe[MAX];
class Graf{
public:
//date membre
vector <int> A[MAX]; //liste de adiacenta
int mM, mN;
int nrComp; //nr comp conexe
static bool viz[MAX];
static int up[MAX];
static int nivel[MAX];
static int S[MAX];
static int top;
int nrCompBiconexe;
//constructor
Graf(int N, int M){
mN = N;
mM = M;
nrComp = 0;
nrCompBiconexe = 0;
}
void CitireGOrientat(){
int x, y;
for(int i = 1; i <= mM; i++){
fin >> x >> y;
A[x].push_back(y);
}
}
void CitireGNeOrientat(){
int x, y;
for(int i = 1; i <= mM; i++){
// citim muchiile
fin >> x >> y;
A[x].push_back(y); //adaugam ambele noduri in lista celuilalt de adiacenta
A[y].push_back(x); //deoarece graful e neorientat
}
}
void BFS(int start);
void DFS(int start);
void ComponenteConexe();
void DFS_Biconex(int start, int father);
void AfisareBiconex();
};
bool Graf :: viz[MAX] ={0};
int Graf :: up[MAX] = {0};
int Graf :: nivel[MAX] = {0};
int Graf :: S[MAX] = {0};
int Graf :: top = 0;
void Graf :: BFS(int start){
int x;
bool viz[MAX] = {0};
queue <int> Q;
// int pr, ul;
// pr = 1;
// ul = 0;
int lg[MAX] = {0}; // lungimea drumului
// vizitam nodul curent
viz[start] = 1;
// il punem in coada
Q.push(start);
// fout<<1;
while ( !Q.empty() ){
x = Q.front();
Q.pop();
// preluam primul element din coada apoi il eliminam din coada
for(int i = 0; i < A[x].size(); i++){
// parcurgem toti vecinii lui x
if(viz[A[x][i]] == 0){ // daca nu am mai vizitat vecinul asta{
Q.push(A[x][i]);
// il vizitam
viz[A[x][i]] = 1;
// creste lungimea drumului
lg[A[x][i]] = lg[x] + 1;
}
}
}
for(int i = 1; i <= mN; i++)
if(viz[i] != 0)
fout << lg[i] << " ";
else
fout << -1 << " ";
}
void Graf :: DFS (int start){
viz[start] = 1;
// vizitam nodul din care plecam
for(int i = 0; i < A[start].size(); i++){
// parcurgem toti vecinii nodului start
if(!viz[A[start][i]] ){
// daca nu am mai vizitat acest vecin
DFS(A[start][i]);
}
}
}
void Graf :: ComponenteConexe(){
for(int i = 1; i <= mN; i++){
if(!viz[i]){
nrComp++;
DFS(i);
}
}
}
void Graf :: DFS_Biconex(int start, int father )
{
viz[start] = 1;
// vizitam nodul din care plecam
up[start] = nivel[start];
S[++top] = start; // adaugam startul in stiva
for ( auto i : A[start] ){
// parcurgem toti vecinii nodului start
if ( i == father ) continue;
//daca nu e nodul din care am venit
if ( viz[i] ){
// daca am mai vizitat acest vecin
up[start] = min(up[start], nivel[i]);
}
else{
nivel[i] = nivel[start] + 1;
DFS_Biconex(i, start);
if ( up[i] >= nivel[start] ){
nrCompBiconexe++;
while ( top && S[top] != i ){
compBiconexe[nrCompBiconexe].push_back(S[top--]);
}
compBiconexe[nrCompBiconexe].push_back(S[top--]);
compBiconexe[nrCompBiconexe].push_back(start);
}
up[start] = min(up[start], up[i]);
}
}
}
void Graf :: AfisareBiconex()
{
fout << nrCompBiconexe << "\n";
for ( int i = 1; i <= nrCompBiconexe; i++ ){
for ( auto j : compBiconexe[i] )
fout << j << " ";
fout << "\n";
}
}
int main(){
int N, M, S;
int x,y;
fin >> N >> M >> S;
// fout << 1;
Graf G(N,M);
G.CitireGOrientat();
G.BFS(S);
return 0;
}