Cod sursa(job #2790792)

Utilizator LacatusLacatus Catalin-Petru Lacatus Data 29 octombrie 2021 15:39:14
Problema Parcurgere DFS - componente conexe Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 6.95 kb
 #include<iostream>
#include<vector>
#include <queue>
#include<fstream>
using namespace std;
class Graf { ///clasa abstracta graf
private:
	int Nr_noduri, Nr_muchii;
	vector<vector<int>>Lista_de_adiacenta;
public:
	Graf(int, int);
	virtual void citire(istream& in)=0;
	virtual void afisare(ostream& out)=0;
	virtual ~Graf()=0;
};

Graf::Graf(int Nr_noduri = 0, int Nr_muchii = 0) {
	this->Nr_noduri = Nr_noduri;
	this->Nr_muchii = Nr_muchii;
}

Graf::~Graf() {
	this->Nr_noduri = 0;
	this->Nr_muchii = 0;
}

class Graf_orientat: public Graf ///graf orientat
{
private:
	int Nr_noduri, Nr_muchii;
	vector<vector<int>>Lista_de_adiacenta;
public:
	Graf_orientat(int, int, vector<vector<int>>);
	~Graf_orientat();
	void adauga_in_lista_de_adiacenta(int, int);
	void citire(istream& in);
	void afisare(ostream& out);
	friend istream& operator >>(istream&, Graf_orientat&);
	friend ostream& operator <<(ostream&, Graf_orientat&);
	vector<int> BFS(int);
	void DFS(int, vector<int>&);
};

Graf_orientat::Graf_orientat(int Nr_noduri = 0, int Nr_muchii = 0, vector<vector<int>>Lista_de_adiacenta = {}):Graf(Nr_noduri,Nr_muchii) {
	//this->Nr_noduri = Nr_noduri;
	//this->Nr_muchii = Nr_muchii;
	this->Lista_de_adiacenta.resize(Nr_noduri + 1);

	for (int i = 1; i < Lista_de_adiacenta.size(); i++)
		for (int j = 0; j < Lista_de_adiacenta[i].size(); j++)
			this->Lista_de_adiacenta[i].push_back(Lista_de_adiacenta[i][j]);
}

void Graf_orientat::adauga_in_lista_de_adiacenta(int nod_stang, int nod_drept) {
	this->Lista_de_adiacenta[nod_stang].push_back(nod_drept);
}

void Graf_orientat::citire(istream& in) {

	in >> Nr_noduri;
	in >> Nr_muchii;
	this->Lista_de_adiacenta.resize(Nr_noduri + 1);
	int stanga, dreapta;
	for (int i = 1; i <= Nr_muchii; i++)
	{
		in >> stanga;
		in >> dreapta;
		adauga_in_lista_de_adiacenta(stanga, dreapta);
	}

}

void Graf_orientat::afisare(ostream& out) {

	out << Nr_noduri << " ";
	out << Nr_muchii << endl;
	for (int i = 1; i < Lista_de_adiacenta.size(); i++) {
		for (int j = 0; j < Lista_de_adiacenta[i].size(); j++)
			out << Lista_de_adiacenta[i][j] << " ";
	}
}

istream& operator>>(istream& in, Graf_orientat& g)
{
	g.citire(in);
	return in;
}
ostream& operator<<(ostream& out, Graf_orientat& g)
{
	g.afisare(out);
	return out;
}

Graf_orientat::~Graf_orientat() {
	this->Lista_de_adiacenta.clear();
	this->Nr_muchii = 0;
	this->Nr_noduri = 0;

}

vector<int> Graf_orientat::BFS(int Start_nod) {
	vector<int>Distante(this->Nr_noduri + 1, -1);
	deque<int>coada;
	coada.push_back(Start_nod);
	Distante[Start_nod] = 0;

	while (!coada.empty()) {
		int primul_nod_din_coada = coada.front();
		for (int i = 0; i < Lista_de_adiacenta[primul_nod_din_coada].size(); i++) {
			int nod_curent = Lista_de_adiacenta[primul_nod_din_coada][i];
			if (Distante[nod_curent] == -1) {
				coada.push_back(nod_curent);
				Distante[nod_curent] = Distante[primul_nod_din_coada] + 1;
			}
		}
		coada.pop_front();
	}
	return Distante;
}

class Graf_neorientat : public Graf   ///graf neorientat
{
private:
	int Nr_noduri, Nr_muchii;
	vector<vector<int>>Lista_de_adiacenta;
public:
	Graf_neorientat(int, int, vector<vector<int>>);
	~Graf_neorientat();
	int get_nr_noduri();
	void adauga_in_lista_de_adiacenta(int, int);
	void citire(istream& in);
	void afisare(ostream& out);
	friend istream& operator >>(istream&, Graf_neorientat&);
	friend ostream& operator <<(ostream&, Graf_neorientat&);
	vector<int> BFS(int);
	void DFS(int, vector<int>&);
};

Graf_neorientat::Graf_neorientat(int Nr_noduri = 0, int Nr_muchii = 0, vector<vector<int>>Lista_de_adiacenta = {}) :Graf(Nr_noduri, Nr_muchii) {
	//this->Nr_noduri = Nr_noduri;
	//this->Nr_muchii = Nr_muchii;
	this->Lista_de_adiacenta.resize(Nr_noduri + 1);

	for (int i = 1; i < Lista_de_adiacenta.size(); i++)
		for (int j = 0; j < Lista_de_adiacenta[i].size(); j++) {
			this->Lista_de_adiacenta[i].push_back(Lista_de_adiacenta[i][j]);
			this->Lista_de_adiacenta[j].push_back(Lista_de_adiacenta[i][j]);
		}
}

int Graf_neorientat::get_nr_noduri() {
	return Nr_noduri;
}

void Graf_neorientat::adauga_in_lista_de_adiacenta(int nod_stang, int nod_drept) {
	this->Lista_de_adiacenta[nod_stang].push_back(nod_drept);
}

void Graf_neorientat::citire(istream& in) {

	in >> Nr_noduri;
	in >> Nr_muchii;
	this->Lista_de_adiacenta.resize(Nr_noduri + 1);
	int stanga, dreapta;
	for (int i = 1; i <= Nr_muchii; i++)
	{
		in >> stanga;
		in >> dreapta;
		adauga_in_lista_de_adiacenta(stanga, dreapta);
		adauga_in_lista_de_adiacenta(dreapta, stanga);
	}

}

void Graf_neorientat::afisare(ostream& out) {

	out << Nr_noduri << " ";
	out << Nr_muchii << endl;
	for (int i = 1; i < Lista_de_adiacenta.size(); i++) {
		for (int j = 0; j < Lista_de_adiacenta[i].size(); j++)
			out << Lista_de_adiacenta[i][j] << " ";
	}
}

istream& operator>>(istream& in, Graf_neorientat& g)
{
	g.citire(in);
	return in;
}
ostream& operator<<(ostream& out, Graf_neorientat& g)
{
	g.afisare(out);
	return out;
}

Graf_neorientat::~Graf_neorientat() {
	this->Lista_de_adiacenta.clear();
	this->Nr_muchii = 0;
	this->Nr_noduri = 0;

}

void Graf_neorientat::DFS(int Nod_start, vector<int>& Vector_vizitati) {
	Vector_vizitati[Nod_start] = 0; ///Marcam nodul de unde incepe dfs-ul ca vizitat

	for (int i = 0; i < Lista_de_adiacenta[Nod_start].size(); i++)///parcurgem vecinii nodului
	{

		int nod_curent = Lista_de_adiacenta[Nod_start][i];
		if (Vector_vizitati[nod_curent] == -1)
			DFS(nod_curent, Vector_vizitati);
	}

}
int Numar_componente_conexe(Graf_neorientat g) {
	int Nr_noduri = g.get_nr_noduri();
	vector<int>Vector_vizitati(Nr_noduri + 1, -1); ///Marcam toate norudrile nevizitate
											   ///-1 =>nod nevizitat
											   ///0 =>nod vizitat
	int Nr_comp_conexe = 0;
	for (int i = 1; i <= Nr_noduri; i++)
	{
		if (Vector_vizitati[i] == -1) {    ///Daca nodul este nevizitat se aplica DFS
			g.DFS(i, Vector_vizitati);
			Nr_comp_conexe++;
		}
	}
	return Nr_comp_conexe;
}

void BFS_infoarena() {           ///BFS - PROBLEMA INFOARENA
	ifstream f_in("bfs.in");
	ofstream f_out("bfs.out");

	int Nr_noduri, Nr_muchii, Start_nod, Nod_st, Nod_dr;
	f_in >> Nr_noduri;
	f_in >> Nr_muchii;
	f_in >> Start_nod;
	vector<vector<int>>Lista_de_adiacenta(Nr_noduri + 1);

	for (int i = 0; i < Nr_muchii; i++)
	{
		f_in >> Nod_st >> Nod_dr;
		Lista_de_adiacenta[Nod_st].push_back(Nod_dr);
	}

	Graf_orientat graf(Nr_noduri, Nr_muchii, Lista_de_adiacenta);

	vector<int> Distante = graf.BFS(Start_nod);
	for (int i = 1; i < Distante.size(); i++)
		f_out << Distante[i] << " ";
	f_in.close();
	f_out.close();
	Lista_de_adiacenta.clear();
}

void DFS_infoarena() {
    ifstream f_in("dfs.in");
    ofstream f_out("dfs.out");
	Graf_neorientat graf;
	f_in >> graf;
	f_out << Numar_componente_conexe(graf);
	f_in.close();
	f_out.close();
}

int main()
{
	///BFS_infoarena();
	DFS_infoarena();

	return 0;
}