Pagini recente » Cod sursa (job #462799) | Cod sursa (job #2322318) | Cod sursa (job #1805982) | Cod sursa (job #2785125) | Cod sursa (job #2820071)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <climits>
using namespace std;
constexpr int INF = INT_MAX;
ifstream fin("ciclueuler.in");
ofstream fout("ciclueuler.out");
struct Edge
{
// easier, cleaner and more expandable alternative to using a tuple for Storing sourceNodes, destinationNodes, weights, capacities etc...
int src;
int dest;
int cost;
Edge ()
{
src = 0;
dest = 0;
cost = 0;
}
Edge(int s, int d, int c = 0)
{
src = s;
dest = d;
cost = c;
}
Edge getReverse()
{
Edge revEdge(dest, src, cost);
return revEdge;
}
};
class Graph
{
// Implementation of << UTILITARY Functions >> for (UN)Directed, (UN)Weighted & (UN)Flowing << Graphs >> ;
bool isDirected;
bool isWeighted;
int nrNodes;
int nrEdges;
vector<vector<Edge>> adjacencyList;
public:
Graph(int n = 0, int m = 0, bool d = false, bool w = false) : nrNodes(n), nrEdges(m), isDirected(d), isWeighted(w){}
void readAdjacencyList();
void addEdge(Edge edge);
void removeEdge(int src, int dst);
vector<int> getEulerCycle();
private:
void EulerianCycleDFS(int startingNode, vector<bool>& visitedEdges, vector<int>& EClist);
};
#pragma region Definitions
void Graph :: readAdjacencyList()
{
adjacencyList.resize(nrNodes + 1);
for (int i = 0; i < nrEdges; i++)
{
Edge edge;
fin >> edge.src >> edge.dest;
if (isWeighted)
edge.cost = i + 1;
addEdge(edge);
nrEdges--;
}
}
void Graph :: addEdge(Edge newEdge)
{
adjacencyList[newEdge.src].push_back(newEdge);
if(!isDirected)
adjacencyList[newEdge.dest].push_back(newEdge.getReverse());
nrEdges++;
}
void Graph :: removeEdge(int src, int dst)
{
for (int i = 0; i < adjacencyList[src].size(); i++)
if (adjacencyList[src][i].src == src && adjacencyList[src][i].dest == dst)
adjacencyList[src].erase(adjacencyList[src].begin() + i);
if (!isDirected)
for (int i = 0; i < adjacencyList[dst].size(); i++)
if (adjacencyList[dst][i].src == src && adjacencyList[dst][i].dest == dst)
adjacencyList[dst].erase(adjacencyList[dst].begin() + i);
nrEdges--;
}
vector<int> Graph :: getEulerCycle()
{
vector<bool> isVisitedEdge(nrEdges + 1, false);
vector<int> EClist;
for (int i = 1; i <= nrNodes; i++)
{
if (adjacencyList[i].size() % 2)
{
EClist.push_back(0);
return EClist;
}
}
EulerianCycleDFS(1, isVisitedEdge, EClist);
if (count(isVisitedEdge.begin(), isVisitedEdge.end(), true) != nrEdges) // if the graph is not connected, an Eulerian Cycle is not possible
EClist.push_back(0);
return EClist;
}
void Graph :: EulerianCycleDFS(int startingNode, vector<bool>& visitedEdges, vector<int>& EClist)
{
for(auto& edge : adjacencyList[startingNode])
if (!visitedEdges[edge.cost])
{
visitedEdges[edge.cost] = true;
EulerianCycleDFS(edge.dest, visitedEdges, EClist);
}
EClist.push_back(startingNode);
}
#pragma endregion
int main()
{
int nodes, edges;
fin >> nodes >> edges;
Graph G(nodes, edges, false, true); // G(nodes, edges, isDirected, isWeighted);
G.readAdjacencyList();
/* ---> EULERIAN CYCLE <--- */
vector<int> EClist = G.getEulerCycle();
if (!EClist.back())
fout << -1;
else
{
EClist.pop_back();
for (auto x : EClist)
fout << x << " ";
}
fin.close();
fout.close();
return 0;
}