Cod sursa(job #2919339)

Utilizator alt_contStefan alt_cont Data 16 august 2022 19:29:46
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.71 kb
	
#include <fstream>

#include <iostream>
	
#include <vector>
	
#include <stack>
	
#include <queue>
	
#include <deque>
	
#include <algorithm>
	
#include <functional>
	
#include <ctime>
	
#include <cassert>
	
 
	
using namespace std;
	
vector<vector<int>> SCC;
	
const int infty = 2*1e9;
	
const int max_matrix = 31;
	
int DEBUG;
	
using Adj_Matrix = array<array<int, max_matrix>, max_matrix>;
	
 
	
// Elements of the adjacency list we use. 
	
// When edge(v, d) is in adj[u], v represents the outvertex and d the weight of the edge from u to v.
	
struct Edge{
	
	int vertex;
	
	int weight;
	
	Edge(int v, int w){
	
		vertex = v, weight = w;
	
	}
	
};
	
 
	
 
	
struct SymmetricEdge{
	
	int from;
	
	int to;
	
	int id;
	
	int weight;
	
	SymmetricEdge(int from, int to, int id, int weight=1): from{from}, to{to}, id{id}, weight{weight} {}
	
};
	
 
	
 
	
// Weighted graph class for the purpose of demonstrating graph algorithms
	
class Graph{
	
	private:
	
		int size;
	
		vector<vector<Edge>> adj;
	
		vector<vector<SymmetricEdge>> sym_adj;
	
 
	
		void dfs_helper(int v, vector<bool>& vis, function<void(int)>, function<void(int)>);
	
		void bfs_helper(vector<bool>& vis, queue<int>& q);
	
 
	
	public:
	
		Graph(int sz) :size {sz}, adj {vector<vector<Edge>>(sz + 1)}, sym_adj {vector<vector<SymmetricEdge>>(sz + 1)} {}
	
 
	
		void add_edge(int v1, int v2, int weight);
	
		void add_symmetric_edge(int v1, int v2, int id, int weight);
	
		void print();
	
 
	
		void dfs(function<void(int)>, function<void(int)>);
	
		void bfs(int start_vertex);
	
 
	
		Graph reverse_graph();
	
		void strongly_connected_components();
	
 
	
		vector<int> minimal_spanning_tree(int source);
	
 
	
		vector<int> shortest_paths_dijkstra(int source);
	
		vector<int> shortest_paths_bellman_ford(int source);
	
 
	
		int** all_shortest_paths(int** adj_matrix);
	
 
	
		vector<int> eulerian_cycle(int number_edges);
	
		void euler_helper(int node, vector<int>& vis, vector<int>& cycle);
	
};
	
 
	
 
	
//Basic utilities, add weighted edge, print to stdout etc.
	
void Graph::add_edge(int v1, int v2, int weight=1){
	
	adj[v1].push_back(Edge(v2, weight));
	
}
	
 
	
 
	
void Graph::add_symmetric_edge(int from, int to, int id, int weight=1){
	
	SymmetricEdge e1(from, to, id, weight);
	
	SymmetricEdge e2(to, from, id, weight);
	
	sym_adj[from].push_back(e1);
	
	sym_adj[to].push_back(e2);
	
}
	
 
	
 
	
void Graph::print(){
	
	for(int i=1; i <= size; ++i){
	
		cout << i << ":";
	
		for(auto edge: adj[i])
	
			printf("(%d, %d) ", edge.vertex, edge.weight);
	
		cout << "\n";
	
	}
	
}

	
 

ifstream fin;
ofstream fout;
int ecount = 0;
int M;
	
 
	
vector<int> Graph::eulerian_cycle(int m){
	M = m;
	// Return {-1} for non eulerian graphs.
	for(int i = 1; i <= size; ++i)
		if(sym_adj[i].size() & 1){
			fout << -1;
			return vector<int> {-1};
		}
	
	vector<int> cycle;
	vector<int> vis(m + 1);
	
	euler_helper(1, vis, cycle);
	return cycle;
}
	
 
	
 
	
void Graph::euler_helper(int node, vector<int>& vis, vector<int>& cycle){
	
	while(!sym_adj[node].empty()){
		SymmetricEdge edge = sym_adj[node].back();
		sym_adj[node].pop_back();
	
		if(!vis[edge.id]){
			vis[edge.id] = 1;
			euler_helper(edge.to, vis, cycle);
		}
	}
 
	cycle.push_back(node);
	
	if(++ecount <= M)
		fout << node << " ";
	
}
	
 
	
 
	
int main(){
	fin.open("ciclueuler.in");
	fout.open("ciclueuler.out"); 

	int n, m, u, v;
	fin >> n >> m;
	Graph g(n);
 
	
	for(int i=1; i <= m; ++i){
		fin >> u >> v;
		g.add_symmetric_edge(u, v, i);
	}
	
	vector<int> cycle;
	cycle = g.eulerian_cycle(m);
}