Pagini recente » Cod sursa (job #255508) | Cod sursa (job #2942928) | Cod sursa (job #2656677) | Cod sursa (job #688014) | Cod sursa (job #999595)
Cod sursa(job #999595)
#include <fstream>
#include <list>
#include <stack>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");
const int MAXN = 100005;
int N, M, a, b;
list<int> graph[MAXN];
queue<int> coada;//folosita pentru BFS
stack<int> stiva;
vector<int> circuit;
int degree[MAXN];
bool visited[MAXN];
void read() {
fin >> N >> M;
for (int i = 0; i < M; ++i) {
fin >> a >> b;
degree[a]++; degree[b]++;//cresc gradul
graph[a].push_back(b);
graph[b].push_back(a);
}
}
void BFS() {
int node;
coada.push(1);
list<int>::iterator it;
do {
node = coada.front();
coada.pop();
for (it = graph[node].begin(); it != graph[node].end(); ++it)
if (!visited[*it]) {
visited[*it] = true;
coada.push(*it);
}
}while (!coada.empty());
}
bool connex() {
BFS();
for (int i = 1; i <= N; ++i)
if (visited[i] == false)
return false;//gasim nod nevizitat => graful nu este conex
return true;
}
bool eulerian() {//este graful eulerian?
if (!connex())//conditia 1: graful este conex
return false;
else
for (int i = 1; i <= N; ++i)
if (degree[i] % 2 == 1)
return false;//conditia 2: toate gradele nodurilor sa fie pare
return true;//daca ambele conditii sunt verificate, inseamna ca graful este eulerian
}
void sterge(int node, int neighbour) {
graph[node].pop_front();//sterg sageata din node -> neighbour
list<int>::iterator it;
for (it = graph[neighbour].begin(); it != graph[neighbour].end(); ++it)//caut neighbour -> node
if (*it == node) {//cand gasesc
graph[node].erase(it);//sterg; it = pointer catre node
break;//opresc cautarea
}
}
void euler(int node) {//lucrez cu o componenta circulara disjuncta (fata de alte componente)
int neighbour;
while (!graph[node].empty()) {//pentru cazul in care avem self-loops, repetam.
//daca node nu mai are vecini, stim ca am ajuns in root, deci am inchis circuitul
//asa ca incercam sa deschidem un alt circuit (care urmeaza sa fie integrat)
//dintr-un nod cu vecini (daca nu gasim astfel de noduri, terminam; vezi solve())
neighbour = graph[node].front();
stiva.push(node);
sterge(node, neighbour);//sterg muchia dintre node si neighbour
node = neighbour;
}
}
void solve() {
int node = 1;
do {
euler(node);
node = stiva.top();
stiva.pop();
circuit.push_back(node);//pentru vizibilitate, copiem nodurie circuitului intr-un vector
}while (!stiva.empty());
}
void write() {
vector<int>::iterator it;
for (it = circuit.begin(); it != circuit.end(); ++it)
fout << *it << ' ';
}
int main() {
read();
if (eulerian()) {
solve();
write();
}else {
fout << -1;
}
fout << '\n';
fin.close();
fout.close();
return 0;
}