// A C++ program to check if a given graph is Eulerian or not
#include<iostream>
#include <list>
using namespace std;
// A class that represents an undirected graph
class Graph
{
int V; // No. of vertices
list<int> *adj; // A dynamic array of adjacency lists
public:
// Constructor and destructor
Graph(int V) {this->V = V; adj = new list<int>[V]; }
~Graph() { delete [] adj; } // To avoid memory leak
// function to add an edge to graph
void addEdge(int v, int w);
// Method to check if this graph is Eulerian or not
int isEulerian();
// Method to check if all non-zero degree vertices are connected
bool isConnected();
// Function to do DFS starting from v. Used in isConnected();
void DFSUtil(int v, bool visited[]);
};
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w);
adj[w].push_back(v); // Note: the graph is undirected
}
void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and print it
visited[v] = true;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
DFSUtil(*i, visited);
}
// Method to check if all non-zero degree vertices are connected.
// It mainly does DFS traversal starting from
bool Graph::isConnected()
{
// Mark all the vertices as not visited
bool visited[V];
int i;
for (i = 0; i < V; i++)
visited[i] = false;
// Find a vertex with non-zero degree
for (i = 0; i < V; i++)
if (adj[i].size() != 0)
break;
// If there are no edges in the graph, return true
if (i == V)
return true;
// Start DFS traversal from a vertex with non-zero degree
DFSUtil(i, visited);
// Check if all non-zero degree vertices are visited
for (i = 0; i < V; i++)
if (visited[i] == false && adj[i].size() > 0)
return false;
return true;
}
/* The function returns one of the following values
0 --> If grpah is not Eulerian
1 --> If graph has an Euler path (Semi-Eulerian)
2 --> If graph has an Euler Circuit (Eulerian) */
int Graph::isEulerian()
{
// Check if all non-zero degree vertices are connected
if (isConnected() == false)
return 0;
// Count vertices with odd degree
int odd = 0;
for (int i = 0; i < V; i++)
if (adj[i].size() & 1)
odd++;
// If count is more than 2, then graph is not Eulerian
if (odd > 2)
return 0;
// If odd count is 2, then semi-eulerian.
// If odd count is 0, then eulerian
// Note that odd count can never be 1 for undirected graph
return (odd)? 1 : 2;
}
// Function to run test cases
void test(Graph &g)
{
int res = g.isEulerian();
if (res == 0)
cout << "graph is not Eulerian\n";
else if (res == 1)
cout << "graph has a Euler path\n";
else
cout << "graph has a Euler cycle\n";
}
// Driver program to test above function
int main()
{
// Let us create and test graphs shown in above figures
Graph g1(5);
g1.addEdge(1, 0);
g1.addEdge(0, 2);
g1.addEdge(2, 1);
g1.addEdge(0, 3);
g1.addEdge(3, 4);
test(g1);
Graph g2(5);
g2.addEdge(1, 0);
g2.addEdge(0, 2);
g2.addEdge(2, 1);
g2.addEdge(0, 3);
g2.addEdge(3, 4);
g2.addEdge(4, 0);
test(g2);
Graph g3(5);
g3.addEdge(1, 0);
g3.addEdge(0, 2);
g3.addEdge(2, 1);
g3.addEdge(0, 3);
g3.addEdge(3, 4);
g3.addEdge(1, 3);
test(g3);
// Let us create a graph with 3 vertices
// connected in the form of cycle
Graph g4(3);
g4.addEdge(0, 1);
g4.addEdge(1, 2);
g4.addEdge(2, 0);
test(g4);
// Let us create a graph with all veritces
// with zero degree
Graph g5(3);
test(g5);
return 0;
}
Ly8gQSBDKysgcHJvZ3JhbSB0byBjaGVjayBpZiBhIGdpdmVuIGdyYXBoIGlzIEV1bGVyaWFuIG9yIG5vdCAKI2luY2x1ZGU8aW9zdHJlYW0+IAojaW5jbHVkZSA8bGlzdD4gCnVzaW5nIG5hbWVzcGFjZSBzdGQ7IAoKLy8gQSBjbGFzcyB0aGF0IHJlcHJlc2VudHMgYW4gdW5kaXJlY3RlZCBncmFwaCAKY2xhc3MgR3JhcGggCnsgCglpbnQgVjsgLy8gTm8uIG9mIHZlcnRpY2VzIAoJbGlzdDxpbnQ+ICphZGo7IC8vIEEgZHluYW1pYyBhcnJheSBvZiBhZGphY2VuY3kgbGlzdHMgCnB1YmxpYzogCgkvLyBDb25zdHJ1Y3RvciBhbmQgZGVzdHJ1Y3RvciAKCUdyYXBoKGludCBWKSB7dGhpcy0+ViA9IFY7IGFkaiA9IG5ldyBsaXN0PGludD5bVl07IH0gCgl+R3JhcGgoKSB7IGRlbGV0ZSBbXSBhZGo7IH0gLy8gVG8gYXZvaWQgbWVtb3J5IGxlYWsgCgoJLy8gZnVuY3Rpb24gdG8gYWRkIGFuIGVkZ2UgdG8gZ3JhcGggCgl2b2lkIGFkZEVkZ2UoaW50IHYsIGludCB3KTsgCgoJLy8gTWV0aG9kIHRvIGNoZWNrIGlmIHRoaXMgZ3JhcGggaXMgRXVsZXJpYW4gb3Igbm90IAoJaW50IGlzRXVsZXJpYW4oKTsgCgoJLy8gTWV0aG9kIHRvIGNoZWNrIGlmIGFsbCBub24temVybyBkZWdyZWUgdmVydGljZXMgYXJlIGNvbm5lY3RlZCAKCWJvb2wgaXNDb25uZWN0ZWQoKTsgCgoJLy8gRnVuY3Rpb24gdG8gZG8gREZTIHN0YXJ0aW5nIGZyb20gdi4gVXNlZCBpbiBpc0Nvbm5lY3RlZCgpOyAKCXZvaWQgREZTVXRpbChpbnQgdiwgYm9vbCB2aXNpdGVkW10pOyAKfTsgCgp2b2lkIEdyYXBoOjphZGRFZGdlKGludCB2LCBpbnQgdykgCnsgCglhZGpbdl0ucHVzaF9iYWNrKHcpOyAKCWFkalt3XS5wdXNoX2JhY2sodik7IC8vIE5vdGU6IHRoZSBncmFwaCBpcyB1bmRpcmVjdGVkIAp9IAoKdm9pZCBHcmFwaDo6REZTVXRpbChpbnQgdiwgYm9vbCB2aXNpdGVkW10pIAp7IAoJLy8gTWFyayB0aGUgY3VycmVudCBub2RlIGFzIHZpc2l0ZWQgYW5kIHByaW50IGl0IAoJdmlzaXRlZFt2XSA9IHRydWU7IAoKCS8vIFJlY3VyIGZvciBhbGwgdGhlIHZlcnRpY2VzIGFkamFjZW50IHRvIHRoaXMgdmVydGV4IAoJbGlzdDxpbnQ+OjppdGVyYXRvciBpOyAKCWZvciAoaSA9IGFkalt2XS5iZWdpbigpOyBpICE9IGFkalt2XS5lbmQoKTsgKytpKSAKCQlpZiAoIXZpc2l0ZWRbKmldKSAKCQkJREZTVXRpbCgqaSwgdmlzaXRlZCk7IAp9IAoKLy8gTWV0aG9kIHRvIGNoZWNrIGlmIGFsbCBub24temVybyBkZWdyZWUgdmVydGljZXMgYXJlIGNvbm5lY3RlZC4gCi8vIEl0IG1haW5seSBkb2VzIERGUyB0cmF2ZXJzYWwgc3RhcnRpbmcgZnJvbSAKYm9vbCBHcmFwaDo6aXNDb25uZWN0ZWQoKSAKeyAKCS8vIE1hcmsgYWxsIHRoZSB2ZXJ0aWNlcyBhcyBub3QgdmlzaXRlZCAKCWJvb2wgdmlzaXRlZFtWXTsgCglpbnQgaTsgCglmb3IgKGkgPSAwOyBpIDwgVjsgaSsrKSAKCQl2aXNpdGVkW2ldID0gZmFsc2U7IAoKCS8vIEZpbmQgYSB2ZXJ0ZXggd2l0aCBub24temVybyBkZWdyZWUgCglmb3IgKGkgPSAwOyBpIDwgVjsgaSsrKSAKCQlpZiAoYWRqW2ldLnNpemUoKSAhPSAwKSAKCQkJYnJlYWs7IAoKCS8vIElmIHRoZXJlIGFyZSBubyBlZGdlcyBpbiB0aGUgZ3JhcGgsIHJldHVybiB0cnVlIAoJaWYgKGkgPT0gVikgCgkJcmV0dXJuIHRydWU7IAoKCS8vIFN0YXJ0IERGUyB0cmF2ZXJzYWwgZnJvbSBhIHZlcnRleCB3aXRoIG5vbi16ZXJvIGRlZ3JlZSAKCURGU1V0aWwoaSwgdmlzaXRlZCk7IAoKCS8vIENoZWNrIGlmIGFsbCBub24temVybyBkZWdyZWUgdmVydGljZXMgYXJlIHZpc2l0ZWQgCglmb3IgKGkgPSAwOyBpIDwgVjsgaSsrKSAKCWlmICh2aXNpdGVkW2ldID09IGZhbHNlICYmIGFkaltpXS5zaXplKCkgPiAwKSAKCQkJcmV0dXJuIGZhbHNlOyAKCglyZXR1cm4gdHJ1ZTsgCn0gCgovKiBUaGUgZnVuY3Rpb24gcmV0dXJucyBvbmUgb2YgdGhlIGZvbGxvd2luZyB2YWx1ZXMgCjAgLS0+IElmIGdycGFoIGlzIG5vdCBFdWxlcmlhbiAKMSAtLT4gSWYgZ3JhcGggaGFzIGFuIEV1bGVyIHBhdGggKFNlbWktRXVsZXJpYW4pIAoyIC0tPiBJZiBncmFwaCBoYXMgYW4gRXVsZXIgQ2lyY3VpdCAoRXVsZXJpYW4pICovCmludCBHcmFwaDo6aXNFdWxlcmlhbigpIAp7IAoJLy8gQ2hlY2sgaWYgYWxsIG5vbi16ZXJvIGRlZ3JlZSB2ZXJ0aWNlcyBhcmUgY29ubmVjdGVkIAoJaWYgKGlzQ29ubmVjdGVkKCkgPT0gZmFsc2UpIAoJCXJldHVybiAwOyAKCgkvLyBDb3VudCB2ZXJ0aWNlcyB3aXRoIG9kZCBkZWdyZWUgCglpbnQgb2RkID0gMDsgCglmb3IgKGludCBpID0gMDsgaSA8IFY7IGkrKykgCgkJaWYgKGFkaltpXS5zaXplKCkgJiAxKSAKCQkJb2RkKys7IAoKCS8vIElmIGNvdW50IGlzIG1vcmUgdGhhbiAyLCB0aGVuIGdyYXBoIGlzIG5vdCBFdWxlcmlhbiAKCWlmIChvZGQgPiAyKSAKCQlyZXR1cm4gMDsgCgoJLy8gSWYgb2RkIGNvdW50IGlzIDIsIHRoZW4gc2VtaS1ldWxlcmlhbi4gCgkvLyBJZiBvZGQgY291bnQgaXMgMCwgdGhlbiBldWxlcmlhbiAKCS8vIE5vdGUgdGhhdCBvZGQgY291bnQgY2FuIG5ldmVyIGJlIDEgZm9yIHVuZGlyZWN0ZWQgZ3JhcGggCglyZXR1cm4gKG9kZCk/IDEgOiAyOyAKfSAKCi8vIEZ1bmN0aW9uIHRvIHJ1biB0ZXN0IGNhc2VzIAp2b2lkIHRlc3QoR3JhcGggJmcpIAp7IAoJaW50IHJlcyA9IGcuaXNFdWxlcmlhbigpOyAKCWlmIChyZXMgPT0gMCkgCgkJY291dCA8PCAiZ3JhcGggaXMgbm90IEV1bGVyaWFuXG4iOyAKCWVsc2UgaWYgKHJlcyA9PSAxKSAKCQljb3V0IDw8ICJncmFwaCBoYXMgYSBFdWxlciBwYXRoXG4iOyAKCWVsc2UKCQljb3V0IDw8ICJncmFwaCBoYXMgYSBFdWxlciBjeWNsZVxuIjsgCn0gCgovLyBEcml2ZXIgcHJvZ3JhbSB0byB0ZXN0IGFib3ZlIGZ1bmN0aW9uIAppbnQgbWFpbigpIAp7IAoJLy8gTGV0IHVzIGNyZWF0ZSBhbmQgdGVzdCBncmFwaHMgc2hvd24gaW4gYWJvdmUgZmlndXJlcyAKCUdyYXBoIGcxKDUpOyAKCWcxLmFkZEVkZ2UoMSwgMCk7IAoJZzEuYWRkRWRnZSgwLCAyKTsgCglnMS5hZGRFZGdlKDIsIDEpOyAKCWcxLmFkZEVkZ2UoMCwgMyk7IAoJZzEuYWRkRWRnZSgzLCA0KTsgCgl0ZXN0KGcxKTsgCgoJR3JhcGggZzIoNSk7IAoJZzIuYWRkRWRnZSgxLCAwKTsgCglnMi5hZGRFZGdlKDAsIDIpOyAKCWcyLmFkZEVkZ2UoMiwgMSk7IAoJZzIuYWRkRWRnZSgwLCAzKTsgCglnMi5hZGRFZGdlKDMsIDQpOyAKCWcyLmFkZEVkZ2UoNCwgMCk7IAoJdGVzdChnMik7IAoKCUdyYXBoIGczKDUpOyAKCWczLmFkZEVkZ2UoMSwgMCk7IAoJZzMuYWRkRWRnZSgwLCAyKTsgCglnMy5hZGRFZGdlKDIsIDEpOyAKCWczLmFkZEVkZ2UoMCwgMyk7IAoJZzMuYWRkRWRnZSgzLCA0KTsgCglnMy5hZGRFZGdlKDEsIDMpOyAKCXRlc3QoZzMpOyAKCgkvLyBMZXQgdXMgY3JlYXRlIGEgZ3JhcGggd2l0aCAzIHZlcnRpY2VzIAoJLy8gY29ubmVjdGVkIGluIHRoZSBmb3JtIG9mIGN5Y2xlIAoJR3JhcGggZzQoMyk7IAoJZzQuYWRkRWRnZSgwLCAxKTsgCglnNC5hZGRFZGdlKDEsIDIpOyAKCWc0LmFkZEVkZ2UoMiwgMCk7IAoJdGVzdChnNCk7IAoKCS8vIExldCB1cyBjcmVhdGUgYSBncmFwaCB3aXRoIGFsbCB2ZXJpdGNlcyAKCS8vIHdpdGggemVybyBkZWdyZWUgCglHcmFwaCBnNSgzKTsgCgl0ZXN0KGc1KTsgCgoJcmV0dXJuIDA7IAp9IAo=