Cod sursa(job #2822733)

Utilizator vasiliumirunamariaVasiliu Miruna-Maria vasiliumirunamaria Data 25 decembrie 2021 02:19:42
Problema Ciclu Eulerian Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 11.01 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#define N 500001
#define oo  0x3f3f3f3f
using namespace std;

ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");






class Graph {


public:
	

	
	int n; //nr de varfuri
	int m; //nr de muchii

	//vector <int> a[N];
	//vector <int> a_t[N];

	//pt roy floyd
	//int matrice[N][N];
	

	//pt apm

	//vector<pair<pair<int, int>, int>> a_cost; //((nod1, nod2), cost) asa retin costul fiecarei muchii
	


	//pt dijkstra
	
	
	//vector<pair<int, int>>a_d[N];

	//pt eulerian
	vector<pair<int, int>>a_e[N];

	
	


	



	Graph(int n, int m)
	{
		this->n = n;
		this->m = m;
	}

	void Citire_orientat();
	void Citire_neorientat();
	void Citire_neorientat_cost(); //pt apm 
	void Citire_cost_D(); //pt dijkstra
	void Citire_Floyd();
	void Citire_Eulerian();
	
	
	
	
	

	
	
	
	void Bellman_Ford(int x);
	

	//------------tema1------------

	//dfs

	void DFS(int x, vector<bool>&viz, stack<int> &S);
	void AfisareDfS();
		
	//bfs

	void BFS(int x);

	//comp tare conexe
	void DFS_T(int x, int ct, vector<bool>&viz_t, vector<int> c[N]);
	void CompTConexe();

	//sortare topologica
	void SortTop();

	//-------tema2---

	//apm
	void Kruskal();
	int Find(int x, vector<int>&tata);
	void Union(int rx, int ry, vector<int>&tata, vector<int>&h, int &nrm_apm);
	
	//paduri de multimi disjuncte
	void Disjoint();

	//disjkstra
	void Dijkstra(int x);

	//------tema3-----

	//roy-floyd
	void Royfloyd();


	//------tema4-----
	void Eulerian();

};






//void Graph::Citire_orientat()
//{
//	int i;
//	int x, y;
//
//	for (i = 0; i < m; i++)
//	{
//		fin >> x >> y;
//		a[x].push_back(y);
//		a_t[y].push_back(x);
//
//	}
//}
//
//void Graph::Citire_neorientat()
//{
//	int i;
//	int x, y;
//	for (i = 0; i < m; i++)
//	{
//		fin >> x >> y;
//		a[x].push_back(y);
//		a[y].push_back(x);
//	}
//}
//
//void Graph::Citire_neorientat_cost()
//{
//	int i;
//	int x, y, z;
//	for (i = 0; i < m; i++)
//	{
//		fin >> x >> y >> z;
//		a_cost.push_back(make_pair(make_pair(x, y), z));
//		// {{x,y},c}
//
//	}
//
//}
//
//void Graph::Citire_cost_D()
//{
//	int i;
//	int x, y, z;
//	for (i = 0; i < m; i++)
//	{
//		fin >> x >> y >> z;
//		a_d[x].push_back(make_pair(y, z));
//		
//	}
//}
//
//void Graph::DFS(int x, vector<bool>& viz, stack<int>& S)
//{
//	int i;
//	viz[x] = 1;
//	for (i = 0; i < a[x].size(); i++)
//		if (!viz[a[x][i]])
//			DFS(a[x][i], viz, S);
//	S.push(x);
//
//
//}
//void Graph::AfisareDfS()
//{
//	vector<bool> viz;
//	stack<int> S;
//	int nrc = 0;
//
//	for (int i = 0; i <= n; i++)
//	{
//		viz.push_back(0);
//		
//	}
//
//	for (int i = 1; i <= n; i++)
//		if (!viz[i])
//		{
//			nrc++;
//			DFS(i, viz, S);
//		}
//
//	fout << nrc;
//
//}
//void Graph::BFS(int x)
//{
//	queue <int> q;
//	vector<bool> viz;
//	int cost[N];
//	int k, i;
//
//
//	for (int i = 0; i <= n; i++)
//		viz.push_back(0);
//	
//	viz[x] = 1;
//
//	cost[x] = 0;
//	q.push(x);
//
//	while (!q.empty())
//	{
//		k = q.front();
//		for (i = 0; i < a[k].size(); i++)
//			if (!viz[a[k][i]])
//			{
//				q.push(a[k][i]);
//				viz[a[k][i]] = 1;
//				cost[a[k][i]] = cost[k] + 1;
//			}
//
//		q.pop();
//	}
//
//	for (i = 1; i <= n; i++)
//		if (viz[i] == 0)
//			fout << -1 << " ";
//		else fout << cost[i] << " ";
//
//
//
//}
//
//
//
//void Graph::SortTop()
//{
//	int i;
//	vector<bool> viz;
//	stack<int> S;
//
//	for (i = 0; i <= n; i++)
//		viz.push_back(0);
//
//	for (i = 1; i <= n; i++)
//		if (!viz[i])
//			DFS(i, viz, S);
//	while (!S.empty())
//	{
//		fout << S.top() << " ";
//		S.pop();
//	}
//}
//
//
//void Graph::DFS_T(int x, int ct, vector<bool> &viz_t, vector<int>c[N])
//{
//	int i;
//	viz_t[x] = 1;
//	c[ct].push_back(x); //pt fiecare nod, din ce comp tconexa face parte
//	for (i = 0; i < a_t[x].size(); i++)
//		if (viz_t[a_t[x][i]] == 0)
//			DFS_T(a_t[x][i], ct, viz_t, c);
//}
//
//void Graph::CompTConexe()
//{
//	int i, j, x, ct = 0;
//	stack<int> S;
//	vector<bool> viz_t;
//
//	//comp tare conexe
//	vector<int>c[N];
//
//	for (int i = 0; i <= n; i++)
//		viz_t.push_back(0);
//
//
//	//parcurgerea grafului
//
//	vector<bool> viz;
//	
//	for (i = 0; i <= n; i++)
//		viz.push_back(0);
//	for (i = 1; i <= n; i++)
//		if (!viz[i])
//			DFS(i, viz, S);
//
//	//------------
//
//	while (!S.empty())
//	{
//		x = S.top();
//		S.pop();
//		if (viz_t[x] == 0)
//		{
//			ct++;
//			DFS_T(x, ct, viz_t, c);
//		}
//
//	}
//	fout << ct << "\n";
//	for (i = 1; i <= ct; i++)
//	{
//		for (j = 0; j < c[i].size(); j++)
//
//			fout << c[i][j] << " ";
//		fout << "\n";
//	}
//
//}
//
//
//bool criteriu_sortare(const pair<pair<int, int>, int>& cost1, const pair<pair<int, int>, int >& cost2)
//{
//	return cost1.second < cost2.second;
//}
//
//int Graph::Find(int x, vector<int>& tata)
//{
//	if (x == tata[x])
//		return x;
//	return Find(tata[x], tata);
//
//
//}
//
//void Graph::Union(int x, int y, vector<int>&tata, vector<int>&h, int &nrm_apm)
//{
//	int rx = Find(x, tata);
//	int ry = Find(y, tata);
//	//nrm_apm = 0;
//
//	if (h[rx] < h[ry])
//	{
//		h[ry] += h[rx];
//		tata[rx] = ry;
//		nrm_apm++;
//
//
//
//	}
//	else
//	{
//		h[rx] += h[ry];
//		tata[ry] = rx;
//		nrm_apm++;
//	}
//}
//void Graph::Kruskal()
//{
//	int cost_total = 0;
//	int i;
//	int cx, cy;
//	int nrm_apm;
//	vector<int> tata;
//	vector<int> h;
//	vector<pair<int, int>>apm;
//
//	nrm_apm = 0;
//
//	for (int i = 0; i <= 2 * n; i++)
//	{
//		tata.push_back(0);
//		h.push_back(0);
//	}
//
//	//pentru fiecare nod initializez vectorul de tata si de inaltime
//	for (i = 0; i <= n; i++)
//	{
//		tata[i] = i;
//		h[i] = 1;
//
//	}
//	//sortam vectorul de muchii ca sa facem apoi partea de greedy
//	//folosim criteriul definit mai sus
//
//	sort(a_cost.begin(), a_cost.end(), criteriu_sortare);
//
//	for (i = 0; i < m; i++)
//	{
//		//gasesc cel mai indepartat stramos al fiecarui nod din muchia i
//		cx = Find(a_cost[i].first.first, tata);
//		cy = Find(a_cost[i].first.second, tata);
//
//		if (cx != cy)
//		{
//			//e bun, inseamna ca nu formeaza cicluri deci o pastram in apm
//
//			apm.push_back(make_pair(a_cost[i].first.first, a_cost[i].first.second));
//
//			cost_total += a_cost[i].second;
//			Union(a_cost[i].first.first, a_cost[i].first.second, tata, h, nrm_apm);
//
//		}
//
//
//	}
//	fout << cost_total << "\n";
//	fout << nrm_apm << "\n";
//	for (i = 0; i < nrm_apm; i++)
//		fout << apm[i].second << " " << apm[i].first << "\n";
//
//}
//
//
//
//
//
//void Graph::Disjoint()
//{
//	int i, x, y, operatie;
//	vector<int> tata;
//	vector<int> h;
//	int nrm = 0;
//
//	for (int i = 0; i <= 2*n; i++)
//	{
//		tata.push_back(0);
//		h.push_back(0);
//	}
//
//	for (i = 0; i <= n; i++)
//	{
//		tata[i] = i;
//		h[i] = 1;
//	}
//
//	for (i = 0; i < m; i++)
//	{
//		fin >>operatie>>x >> y;
//
//		if (operatie == 1)
//		{
//			Union(x, y, tata, h, nrm);
//		}
//		else {
//			if (Find(x, tata) == Find(y, tata))
//				fout << "DA" << "\n";
//			else fout << "NU" << "\n";
//		}
//	}
//}
//
//void Graph::Dijkstra(int s)
//{
//	int i, j , v;
//	int f[N], d[N];
//	priority_queue<pair<int, int> > pq;
//
//	//le setam pe toate ca fiind neexplorate 
//	for (i = 1; i <= n; i++)
//		d[i] = oo;
//	d[s] = 0;
//	f[s] = 1;
//
//	//bagam primul nod in pq
//	pq.push(make_pair(0, s)); //pq compara prima poz si vreau sa le sorteze dupa cost
//
//	while (!pq.empty())
//	{
//		int u = pq.top().second;
//		pq.pop();
//		
//		
//			for (auto i : a_d[u])    //a_d[x] = (nod adiacent, cost muchia(x-nod_adiacent) )
//			{
//				if (d[u] + i.second < d[i.first])
//				{
//					d[i.first] = d[u] + i.second;
//					pq.push(make_pair(d[i.first], i.first));
//				}
//			}
//		
//
//
//	}
//	for (i = 1; i <= n; i++)
//		if (i != s)
//		{
//			if (d[i] != oo)
//				fout << d[i] << " ";
//			else fout << 0 << " ";
//		}
//
//
//}
//
////void Graph::Bellman_Ford(int s)
////{
////	int i, j;
////	bool neg = 0;
////	int viz[N];
////	for (i = 1; i <= n; i++)
////		d[i] = oo;
////	d[s] = 0;
////	f[s] = 1;
////	//bagam primul nod in pq
////	pq.push(make_pair(0, s)); //pq compara prima poz si vreau sa le sorteze dupa cost
////	while (!pq.empty() && !neg)
////	{
////		int u = pq.top().second;
////		pq.pop();
////		f[s] = 0;
////
////		for (auto i : a_d[u])    //a_d[x] = (nod adiacent, cost muchia(x-nod_adiacent) )
////		{
////			if (d[u] + i.second < d[i.first])
////			{
////				d[i.first] = d[u] + i.second;
////				if (!f[u])
////				{
////					pq.push(make_pair(d[i.first], i.first));
////					f[u] = 1;
////				}
////				viz[u]++;
////				if (viz[u] >= n)
////				{
////					neg = 1;
////					break;
////				}
////			}
////		}
////	}
////
////	if (!neg)
////		{
////			for (i = 2; i <= n; i++)
////				fout << d[i] << " ";
////
////		}
////	else fout << "Ciclu negativ!";
////
////}
////
//void Graph::Citire_Floyd()
//{
//	int i, j;
//	for (i = 1; i <= n; i++)
//		for (j = 1; j <= n; j++)
//		{
//			fin >> matrice[i][j];
//			if (i != j)
//				if (!matrice[i][j])
//					matrice[i][j] = oo;
//		}
//
//
//}
//void Graph::Royfloyd()
//{
//	int i, j, k;
//	for (k = 1; k <= n; k++)
//		for (i = 1; i <= n; i++)
//			for (j = 1; j <= n; j++)
//				if (matrice[i][j] > matrice[i][k] + matrice[k][j])
//					matrice[i][j] = matrice[i][k] + matrice[k][j];
//
//	for (i = 1; i <= n; i++)
//	{
//		for (j = 1; j <= n; j++)
//			if (matrice[i][j] != oo)
//				fout << matrice[i][j] << " ";
//			else fout << 0;
//		fout << "\n";
//	}
//}

void Graph::Citire_Eulerian()
{
	int i, x, y;

	for (i = 0; i < m; i++)
	{
		fin >> x >> y;
		
		a_e[x].push_back(make_pair(y, i));
		a_e[y].push_back(make_pair(x, i));
		

	}

}

int CheckEulerian(vector<pair<int, int>>a_e[N],  int n)
{
	int i,ct = 0;

	for (i = 1; i <= n; i++)
		if (a_e[i].size() % 2 == 1)
			ct++;

	if (ct > 2) return 0;
	return 1;

}

void Solve_Euler(vector<pair<int, int>>a_e[N], int n, int k, vector<int> euler, stack<int> S)
{
	int i, j;
	vector<bool> viz;
	for (i = 0; i <= n + 5; i++)
		viz.push_back(0);
	S.push(k);
	while (!S.empty())
	{
		int x = S.top();

		if (a_e[x].size())
		{
			int e = a_e[x].back().first;
			int muchie = a_e[x].back().second;
			a_e[x].pop_back();

			if (!viz[muchie])
			{
				viz[muchie] = 1;
				S.push(e);
				

			}
		}
		else
		{
			S.pop();
			fout << x << " ";
		}



			

	}

}
void Graph::Eulerian()
{
	int i, j, x, y;
	
	stack<int> S;
	vector<int> euler;

	
	if (CheckEulerian(a_e, n))
	{
		Solve_Euler(a_e, n, 1, euler, S);
		
		//fout << 1;
	}
	else fout << -1;
}
int main()
{

	int n, m;

	fin >> n >> m;
	Graph g(n, m);
	g.Citire_Eulerian();
	g.Eulerian();




	return 0;
}