Cod sursa(job #3149839)

Utilizator daristyleBejan Darius-Ramon daristyle Data 13 septembrie 2023 09:35:22
Problema Ciclu Eulerian Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.46 kb
#include <fstream>
#include <vector>
#include <stack>

using namespace std;

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


struct Edge{
    int u, v;
    bool used;

    int getNeighbour(int node){
        return (node == u)?v:u;
    }

    void useEdge(){
        used = true;
    }
};
const int NODES_MAX = 1e5;
const int EDGES_MAX = 5e5;
Edge edge[EDGES_MAX];
vector<int> edgeIndex[NODES_MAX];
int edgeIterator[NODES_MAX]{};
vector<int> cycle;
stack<int> recursionStack;
bool marked[NODES_MAX];

inline void addEdge(int u, int v, int i){
    edge[i] = {u, v, false};
	edgeIndex[u].push_back(i);
	edgeIndex[v].push_back(i);
}

inline bool hasNeighbours(const int& node){
	return edgeIterator[node] < edgeIndex[node].size();
}

void MoveIteratorToNextEdge(int node){
    while(edgeIterator[node] < edgeIndex[node].size() && edge[edgeIndex[node][edgeIterator[node]]].used)
        ++edgeIterator[node];
}

inline int ChooseANeighbourAndErase(const int& node){
	int neighbour = edge[edgeIndex[node][edgeIterator[node]]].getNeighbour(node);
	edge[edgeIndex[node][edgeIterator[node]]].useEdge();
	MoveIteratorToNextEdge(node);
	MoveIteratorToNextEdge(neighbour);
	return neighbour;
}

void euler(int node){
	recursionStack.push(node);
	while(!recursionStack.empty()){
		node = recursionStack.top();

		if(hasNeighbours(node)){
			node = ChooseANeighbourAndErase(node);
			recursionStack.push(node);
		}else{
			cycle.push_back(node);
			recursionStack.pop();
		}
	}

	/*while(hasNeighbours(node)){
		int neighbour = ChooseANeighbourAndErase(node);
		euler(neighbour);
	}

	cycle.push_back(node);*/
}

int dfs(int node){
	int retval = 1;
	marked[node] = true;
	for(auto i: edgeIndex[node]){
        int neighbour = edge[i].getNeighbour(node);
		if(!marked[neighbour])
			retval += dfs(neighbour);
	}

	return retval;
}

inline bool isConex(int nodes){
	return dfs(0) == nodes;
}

inline bool isEulerian(int nodes){
	int odds = 0;
	for(int node = 0; node < nodes; ++node)
		odds += edgeIndex[node].size() & 1;

	return !odds && isConex(nodes);
}

int main(){
	int nodes, edges, u, v;
	fin >> nodes >> edges;
	for(int i = 0; i < edges; ++i){
		fin >> u >> v;

		addEdge(u - 1, v - 1, i);
	}

	if(isEulerian(nodes)){

		euler(0);
		cycle.pop_back();

		for(auto x: cycle)
			fout << x + 1 << ' ';
		fout.put('\n');
	}else
		fout << "-1\n";

	fin.close();
	fout.close();
	return 0;
}