Pagini recente » Istoria paginii utilizator/spirit | Monitorul de evaluare | Cod sursa (job #2583889) | Fotbal3 | Cod sursa (job #1957745)
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
class Graph {
public:
class Edge {
public:
Edge(const int _from, const int _to):
from(_from),
to(_to) {}
int From() const {
return from;
}
int To() const {
return to;
}
private:
int from, to;
};
static const int NIL = -1;
Graph(const int _v = 0):
v(_v),
edges(vector<Edge>()),
vertexEdges(vector< vector< pair<int, int> > >(_v, vector< pair<int, int> >())),
degree(vector<int>(_v, 0)) {}
int V() const {
return v;
}
Edge GetEdge(const int e) const {
return edges[e];
}
vector< pair<int, int> >::const_iterator EdgesBegin(const int x) const {
return vertexEdges[x].begin();
}
vector< pair<int, int> >::const_iterator EdgesEnd(const int x) const {
return vertexEdges[x].end();
}
void AddEdge(const Edge &e) {
vertexEdges[e.From()].push_back(make_pair(e.To(), int(edges.size())));
vertexEdges[e.To()].push_back(make_pair(e.From(), int(edges.size())));
edges.push_back(e);
++degree[e.From()];
++degree[e.To()];
}
vector< pair<int, int> > GetEulerianCycle() const {
if (!IsEulerianGraph())
return vector< pair<int, int> >();
vector<int> eulerDegree = degree;
vector<bool> usedEdges = vector<bool>(int(edges.size()), false);
vector< pair<int, int> > stack, cycle;
int x = 0;
do {
Euler(x, eulerDegree, usedEdges, stack);
x = stack.back().second;
cycle.push_back(stack.back());
stack.pop_back();
} while (!stack.empty());
reverse(cycle.begin(), cycle.end());
return cycle;
}
bool IsEulerianGraph() const {
for (int x = 0; x < v; ++x)
if (degree[x] % 2 != 0)
return false;
return IsConnected();
}
bool IsConnected() const {
vector<bool> used;
BFS(0, used);
for (int x = 0; x < v; ++x)
if (!used[x])
return false;
return true;
}
private:
int v;
vector<Edge> edges;
vector< vector< pair<int, int> > > vertexEdges;
vector<int> degree;
void BFS(const int source, vector<bool> &used) const {
used = vector<bool>(v, false);
queue<int> q;
q.push(source);
used[source] = true;
for (; !q.empty(); q.pop()) {
int x = q.front();
used[x] = true;
for (vector< pair<int, int> >::const_iterator e = vertexEdges[x].begin(); e != vertexEdges[x].end(); ++e) {
if (!used[e->first]) {
q.push(e->first);
used[e->first] = true;
}
}
}
}
int GetEulerDegree(const int x, vector<int> &eulerDegree, vector<bool> &usedEdges) const {
for (; eulerDegree[x] > 0 && usedEdges[vertexEdges[x][eulerDegree[x] - 1].second]; --eulerDegree[x]);
return eulerDegree[x];
}
void Euler(int x, vector<int> &eulerDegree, vector<bool> &usedEdges, vector< pair<int, int> > &stack) const {
for (int y, e; GetEulerDegree(x, eulerDegree, usedEdges) > 0; x = y) {
y = vertexEdges[x][GetEulerDegree(x, eulerDegree, usedEdges) - 1].first;
e = vertexEdges[x][GetEulerDegree(x, eulerDegree, usedEdges) - 1].second;
stack.push_back(make_pair(e, x));
usedEdges[e] = true;
}
}
};
Graph G;
vector< pair<int, int> > Cycle;
void Solve() {
Cycle = G.GetEulerianCycle();
}
void Read() {
ifstream cin("ciclueuler.in");
int v, e;
cin >> v >> e;
G = Graph(v);
for (; e > 0; --e) {
int x, y;
cin >> x >> y;
G.AddEdge(Graph::Edge(--x, --y));
}
cin.close();
}
void Print() {
ofstream cout("ciclueuler.out");
if (Cycle.empty()) {
cout << "-1\n";
} else {
for (int i = 0; i < int(Cycle.size()); ++i)
cout << Cycle[i].second + 1 << " ";
cout << "\n";
}
cout.close();
}
int main() {
Read();
Solve();
Print();
return 0;
}