Open In App
Related Articles

# Paths to travel each nodes using each edge (Seven Bridges of Königsberg)

There are n nodes and m bridges in between these nodes. Print the possible path through each node using each edges (if possible), traveling through each edges only once.

Examples :

```Input : [[0, 1, 0, 0, 1],
[1, 0, 1, 1, 0],
[0, 1, 0, 1, 0],
[0, 1, 1, 0, 0],
[1, 0, 0, 0, 0]]

Output : 5 -> 1 -> 2 -> 4 -> 3 -> 2

Input : [[0, 1, 0, 1, 1],
[1, 0, 1, 0, 1],
[0, 1, 0, 1, 1],
[1, 1, 1, 0, 0],
[1, 0, 1, 0, 0]]

Output : "No Solution"```

It is one of the famous problems in Graph Theory and known as problem of “Seven Bridges of Königsberg”. This problem was solved by famous mathematician Leonhard Euler in 1735. This problem is also considered as the beginning of Graph Theory.

The problem back then was that: There was 7 bridges connecting 4 lands around the city of Königsberg in Prussia. Was there any way to start from any of the land and go through each of the bridges once and only once? Please see these wikipedia images for more clarity.

Euler first introduced graph theory to solve this problem. He considered each of the lands as a node of a graph and each bridge in between as an edge in between. Now he calculated if there is any Eulerian Path in that graph. If there is an Eulerian path then there is a solution otherwise not.
Problem here, is a generalized version of the problem in 1735.

Below is the implementation :

## C++

 `// A C++ program print Eulerian Trail in a``// given Eulerian or Semi-Eulerian Graph``#include ``#include ``#include ``#include ``using` `namespace` `std;` `// A class that represents an undirected graph``class` `Graph``{``// No. of vertices``    ``int` `V;` `    ``// A dynamic array of adjacency lists``    ``list<``int``> *adj;``public``:` `    ``// Constructor and destructor``    ``Graph(``int` `V)``    ``{``        ``this``->V = V;``        ``adj = ``new` `list<``int``>[V];``    ``}``    ``~Graph()``    ``{``        ``delete` `[] adj;``    ``}` `    ``// functions to add and remove edge``    ``void` `addEdge(``int` `u, ``int` `v)``    ``{``        ``adj[u].push_back(v);``        ``adj[v].push_back(u);``    ``}` `    ``void` `rmvEdge(``int` `u, ``int` `v);` `    ``// Methods to print Eulerian tour``    ``void` `printEulerTour();``    ``void` `printEulerUtil(``int` `s);` `    ``// This function returns count of vertices``    ``// reachable from v. It does DFS``    ``int` `DFSCount(``int` `v, ``bool` `visited[]);` `    ``// Utility function to check if edge u-v``    ``// is a valid next edge in Eulerian trail or circuit``    ``bool` `isValidNextEdge(``int` `u, ``int` `v);``};` `/* The main function that print Eulerian Trail.``It first finds an odd degree vertex (if there is any)``and then calls printEulerUtil() to print the path */``void` `Graph::printEulerTour()``{``    ``// Find a vertex with odd degree``    ``int` `u = 0;` `    ``for` `(``int` `i = 0; i < V; i++)``        ``if` `(adj[i].size() & 1)``        ``{``            ``u = i;``            ``break``;``        ``}` `    ``// Print tour starting from oddv``    ``printEulerUtil(u);``    ``cout << endl;``}` `// Print Euler tour starting from vertex u``void` `Graph::printEulerUtil(``int` `u)``{` `    ``// Recur for all the vertices adjacent to``    ``// this vertex``    ``list<``int``>::iterator i;``    ``for` `(i = adj[u].begin(); i != adj[u].end(); ++i)``    ``{``        ``int` `v = *i;` `        ``// If edge u-v is not removed and it's a``        ``// valid next edge``        ``if` `(v != -1 && isValidNextEdge(u, v))``        ``{``            ``cout << u << ``"-"` `<< v << ``" "``;``            ``rmvEdge(u, v);``            ``printEulerUtil(v);``        ``}``    ``}``}` `// The function to check if edge u-v can be considered``// as next edge in Euler Tout``bool` `Graph::isValidNextEdge(``int` `u, ``int` `v)``{` `    ``// The edge u-v is valid in one of the following``    ``// two cases:` `    ``// 1) If v is the only adjacent vertex of u``    ``int` `count = 0; ``// To store count of adjacent vertices``    ``list<``int``>::iterator i;``    ``for` `(i = adj[u].begin(); i != adj[u].end(); ++i)``        ``if` `(*i != -1)``            ``count++;``    ``if` `(count == 1)``        ``return` `true``;`  `    ``// 2) If there are multiple adjacents, then u-v``    ``//    is not a bridge``    ``// Do following steps to check if u-v is a bridge` `    ``// 2.a) count of vertices reachable from u``    ``bool` `visited[V];``    ``memset``(visited, ``false``, V);``    ``int` `count1 = DFSCount(u, visited);` `    ``// 2.b) Remove edge (u, v) and after removing``    ``// the edge, count vertices reachable from u``    ``rmvEdge(u, v);``    ``memset``(visited, ``false``, V);``    ``int` `count2 = DFSCount(u, visited);` `    ``// 2.c) Add the edge back to the graph``    ``addEdge(u, v);` `    ``// 2.d) If count1 is greater, then edge (u, v)``    ``// is a bridge``    ``return` `(count1 > count2)? ``false``: ``true``;``}` `// This function removes edge u-v from graph.``// It removes the edge by replacing adjacent``// vertex value with -1.``void` `Graph::rmvEdge(``int` `u, ``int` `v)``{``    ``// Find v in adjacency list of u and replace``    ``// it with -1``    ``list<``int``>::iterator iv = find(adj[u].begin(),``                                ``adj[u].end(), v);``    ``*iv = -1;`  `    ``// Find u in adjacency list of v and replace``    ``// it with -1``    ``list<``int``>::iterator iu = find(adj[v].begin(),``                                  ``adj[v].end(), u);``    ``*iu = -1;``}` `// A DFS based function to count reachable``// vertices from v``int` `Graph::DFSCount(``int` `v, ``bool` `visited[])``{``    ``// Mark the current node as visited``    ``visited[v] = ``true``;``    ``int` `count = 1;` `    ``// Recur for all vertices adjacent to this vertex``    ``list<``int``>::iterator i;``    ``for` `(i = adj[v].begin(); i != adj[v].end(); ++i)``        ``if` `(*i != -1 && !visited[*i])``            ``count += DFSCount(*i, visited);` `    ``return` `count;``}` `// Driver program to test above function``int` `main()``{``    ``// Let us first create and test``    ``// graphs shown in above figure``    ``Graph g1(4);``    ``g1.addEdge(0, 1);``    ``g1.addEdge(0, 2);``    ``g1.addEdge(1, 2);``    ``g1.addEdge(2, 3);``    ``g1.printEulerTour();` `    ``Graph g3(4);``    ``g3.addEdge(0, 1);``    ``g3.addEdge(1, 0);``    ``g3.addEdge(0, 2);``    ``g3.addEdge(2, 0);``    ``g3.addEdge(2, 3);``    ``g3.addEdge(3, 1);` `    ``// comment out this line and you will see that``    ``// it gives TLE because there is no possible``    ``// output g3.addEdge(0, 3);``    ``g3.printEulerTour();` `    ``return` `0;``}`

## Java

 `// A java program print Eulerian Trail in a``// given Eulerian or Semi-Eulerian Graph``import` `java.util.*;` `public` `class` `GFG{` `    ``// A class that represents an undirected graph``    ``static` `class` `Graph``    ``{``        ``// No. of vertices``        ``int` `V;` `        ``// A dynamic array of adjacency lists``        ``ArrayList> adj;` `        ``// Constructor``        ``Graph(``int` `V)``        ``{``            ``this``.V = V;``            ``adj = ``new` `ArrayList>();` `            ``for``(``int` `i=``0``; i());``            ``}``        ``}`  `        ``// functions to add and remove edge``        ``void` `addEdge(``int` `u, ``int` `v)``        ``{``            ``adj.get(u).add(v);``            ``adj.get(v).add(u);``        ``}` `        ``// This function removes edge u-v from graph.``        ``// It removes the edge by replacing adjacent``        ``// vertex value with -1.``        ``void` `rmvEdge(``int` `u, ``int` `v)``        ``{``            ``// Find v in adjacency list of u and replace``            ``// it with -1``            ``int` `iv = find(adj.get(u), v);``            ``adj.get(u).set(iv, -``1``);`  `            ``// Find u in adjacency list of v and replace``            ``// it with -1``            ``int` `iu = find(adj.get(v), u);``            ``adj.get(v).set(iu, -``1``);``        ``}` `        ``int` `find(ArrayList al, ``int` `v){` `            ``for``(``int` `i=``0``; i count2)? ``false``: ``true``;``        ``}``    ``}` `    ``// Driver program to test above function``    ``public` `static` `void` `main(String args[])``    ``{``        ``// Let us first create and test``        ``// graphs shown in above figure``        ``Graph g1 = ``new` `Graph(``4``);``        ``g1.addEdge(``0``, ``1``);``        ``g1.addEdge(``0``, ``2``);``        ``g1.addEdge(``1``, ``2``);``        ``g1.addEdge(``2``, ``3``);``        ``g1.printEulerTour();` `        ``Graph g3 = ``new` `Graph(``4``);``        ``g3.addEdge(``0``, ``1``);``        ``g3.addEdge(``1``, ``0``);``        ``g3.addEdge(``0``, ``2``);``        ``g3.addEdge(``2``, ``0``);``        ``g3.addEdge(``2``, ``3``);``        ``g3.addEdge(``3``, ``1``);` `        ``// comment out this line and you will see that``        ``// it gives TLE because there is no possible``        ``// output g3.addEdge(0, 3);``        ``g3.printEulerTour();``    ``}``}` `// This code is contributed by adityapande88.`

## Python3

 `# A Python program to print Eulerian trail in a``# given Eulerian or Semi-Eulerian Graph``from` `collections ``import` `defaultdict` `class` `Graph:` `    ``# Constructor and destructor``    ``def` `__init__(``self``, V):``        ``self``.V ``=` `V``        ``self``.adj ``=` `defaultdict(``list``)` `    ``# functions to add and remove edge``    ``def` `addEdge(``self``, u, v):``        ``self``.adj[u].append(v)``        ``self``.adj[v].append(u)` `    ``def` `rmvEdge(``self``, u, v):``        ``self``.adj[u].remove(v)``        ``self``.adj[v].remove(u)` `    ``# Methods to print Eulerian tour``    ``def` `printEulerTour(``self``):``        ``# Find a vertex with odd degree``        ``u ``=` `0``        ``for` `i ``in` `range``(``self``.V):``            ``if` `len``(``self``.adj[i]) ``%` `2` `=``=` `1``:``                ``u ``=` `i``                ``break``        ` `        ``# Print tour starting from oddv``        ``self``.printEulerUtil(u)``        ``print``()` `    ``def` `printEulerUtil(``self``, u):``        ``# Recur for all the vertices adjacent to this vertex``        ``for` `v ``in` `self``.adj[u]:``            ``# If edge u-v is not removed and it's a valid next edge``            ``if` `v !``=` `-``1` `and` `self``.isValidNextEdge(u, v):``                ``print``(u, ``"-"``, v, ``" "``, end``=``"")``                ``self``.rmvEdge(u, v)``                ``self``.printEulerUtil(v)` `    ``# The function to check if edge u-v can be considered``    ``# as next edge in Euler Tout``    ``def` `isValidNextEdge(``self``, u, v):``        ``# The edge u-v is valid in one of the following``        ``# two cases:` `        ``# 1) If v is the only adjacent vertex of u``        ``count ``=` `0`  `# To store count of adjacent vertices``        ``for` `i ``in` `self``.adj[u]:``            ``if` `i !``=` `-``1``:``                ``count ``+``=` `1``        ``if` `count ``=``=` `1``:``            ``return` `True` `        ``# 2) If there are multiple adjacents, then u-v is not a bridge``        ``# Do following steps to check if u-v is a bridge``        ``# 2.a) count of vertices reachable from u``        ``visited ``=` `[``False``] ``*` `(``self``.V)``        ``count1 ``=` `self``.DFSCount(u, visited)` `        ``# 2.b) Remove edge (u, v) and after removing``        ``# the edge, count vertices reachable from u``        ``self``.rmvEdge(u, v)``        ``visited ``=` `[``False``] ``*` `(``self``.V)``        ``count2 ``=` `self``.DFSCount(u, visited)` `        ``# 2.c) Add the edge back to the graph``        ``self``.addEdge(u, v)` `        ``# 2.d) If count1 is greater, then edge (u, v) is a bridge``        ``return` `False` `if` `count1 > count2 ``else` `True` `    ``# A DFS based function to count reachable vertices from v``  ` `    ``def` `DFSCount(``self``, v, visited):``        ``# Mark the current node as visited``        ``visited[v] ``=` `True``        ``count ``=` `1``        ``# Recur for all the vertices adjacent to this vertex``        ``for` `i ``in` `self``.adj[v]:``            ``if` `not` `visited[i]:``                ``count ``+``=` `self``.DFSCount(i, visited)``        ``return` `count``    ``# utility function to form edge between two vertices``    ``# source and dest``    ``def` `makeEdge(src, dest):``        ``graph.addEdge(src, dest)` `# Driver program to test above functions``def` `main():``    ``# Let us first create and test``    ``# graphs shown in above figure``    ``g1 ``=` `Graph(``4``)``    ``g1.addEdge(``0``, ``1``)``    ``g1.addEdge(``0``, ``2``)``    ``g1.addEdge(``1``, ``2``)``    ``g1.addEdge(``2``, ``3``)``    ``g1.printEulerTour()`` ` `    ``g3 ``=` `Graph(``4``)``    ``g3.addEdge(``0``, ``1``)``    ``g3.addEdge(``1``, ``0``)``    ``g3.addEdge(``0``, ``2``)``    ``g3.addEdge(``2``, ``0``)``    ``g3.addEdge(``2``, ``3``)``    ``g3.addEdge(``3``, ``1``)` `    ``# comment out this line and you will see that``    ``# it gives TLE because there is no possible``    ``# output g3.addEdge(0, 3);``    ``g3.printEulerTour()` `if` `__name__ ``=``=` `"__main__"``:``    ``main()` `    ``# This code is contributed by vikramshirsath177`

## Javascript

 `// A Javascript program print Eulerian Trail in a given``// Eulerian or Semi-Eulerian Graph` `      ``// A class that represents an undirected graph``      ``class Graph {``        ``constructor(V) {``          ``this``.V = V; ``// No. of vertices``          ``//A dynamic array of adjacency lists``          ``this``.adj = Array.from(Array(V), () => ``new` `Array());``        ``}` `        ``// functions to add and remove edge``        ``addEdge(u, v) {``          ``this``.adj[u].push(v);``          ``this``.adj[v].push(u);``        ``}` `        ``// This function removes edge u-v from graph.``        ``// It removes the edge by replacing adjacent``        ``// vertex value with -1.``        ``rmvEdge(u, v) {``          ``// Find v in adjacency list of u and replace``          ``// it with -1` `          ``for` `(let i = 0; i < ``this``.adj[u].length; i++) {``            ``if` `(``this``.adj[u][i] == v) {``              ``this``.adj[u][i] = -1;``              ``break``;``            ``}``          ``}` `          ``// Find u in adjacency list of v and replace``          ``// it with -1` `          ``for` `(let i = 0; i < ``this``.adj[v].length; i++) {``            ``if` `(``this``.adj[v][i] == u) {``              ``this``.adj[v][i] = -1;``              ``break``;``            ``}``          ``}``        ``}` `        ``// Methods to print Eulerian tour``        ``printEulerTour() {``          ``// Find a vertex with odd degree``          ``let u = 0;` `          ``for` `(let i = 0; i < ``this``.V; i++)``            ``if` `(``this``.adj[i].length & 1) {``              ``u = i;``              ``break``;``            ``}` `          ``// Print tour starting from oddv``          ``this``.printEulerUtil(u);``          ``console.log(``"   "``);``        ``}` `        ``//Print Euler tour starting from vertex u``        ``printEulerUtil(u) {``          ``{``            ``// Recur for all the vertices adjacent to``            ``// this vertex` `            ``for` `(let j ``in` `this``.adj[u]) {``              ``let v = ``this``.adj[u][j];` `              ``// If edge u-v is not removed and it's a``              ``// valid next edge``              ``if` `(v != -1 && ``this``.isValidNextEdge(u, v)) {``                ``console.log(u + ``"-"` `+ v);``                ``this``.rmvEdge(u, v);``                ``this``.printEulerUtil(v);``              ``}``            ``}``          ``}``        ``}` `        ``// This function returns count of vertices``        ``// reachable from v. It does DFS``        ``DFSCount(v, visited) {``          ``// Mark the current node as visited``          ``visited[v] = ``true``;``          ``let count = 1;` `          ``// Recur for all vertices adjacent to this vertex` `          ``for` `(let j ``in` `this``.adj[v]) {``            ``let i = ``this``.adj[v][j];``            ``if` `(i != -1 && !visited[i]) count += ``this``.DFSCount(i, visited);``          ``}``          ``return` `count;``        ``}` `        ``// The function to check if edge u-v can be considered``        ``// as next edge in Euler Tout``        ``isValidNextEdge(u, v) {``          ``// The edge u-v is valid in one of the following``          ``// two cases:` `          ``// 1) If v is the only adjacent vertex of u``          ``let count = 0; ``// To store count of adjacent vertices` `          ``for` `(let j ``in` `this``.adj[u]) {``            ``let i = ``this``.adj[u][j];``            ``if` `(i != -1) count++;``          ``}``          ``if` `(count == 1) ``return` `true``;` `          ``// 2) If there are multiple adjacents, then u-v``          ``//    is not a bridge``          ``// Do following steps to check if u-v is a bridge` `          ``// 2.a) count of vertices reachable from u``          ``let visited = ``new` `Array(``this``.V);``          ``visited.fill(``false``);``          ``let count1 = ``this``.DFSCount(u, visited);` `          ``// 2.b) Remove edge (u, v) and after removing``          ``// the edge, count vertices reachable from u``          ``this``.rmvEdge(u, v);``          ``visited.fill(``false``);``          ``let count2 = ``this``.DFSCount(u, visited);` `          ``// 2.c) Add the edge back to the graph``          ``this``.addEdge(u, v);` `          ``// 2.d) If count1 is greater, then edge (u, v)``          ``// is a bridge``          ``return` `count1 > count2 ? ``false` `: ``true``;``        ``}``      ``}` `      ``// Driver program to test above function` `      ``// Let us first create and test``      ``// graphs shown in above figure``      ``let g1 = ``new` `Graph(4);``      ``g1.addEdge(0, 1);``      ``g1.addEdge(0, 2);``      ``g1.addEdge(1, 2);``      ``g1.addEdge(2, 3);``      ``g1.printEulerTour();` `      ``let g3 = ``new` `Graph(4);``      ``g3.addEdge(0, 1);``      ``g3.addEdge(1, 0);``      ``g3.addEdge(0, 2);``      ``g3.addEdge(2, 0);``      ``g3.addEdge(2, 3);``      ``g3.addEdge(3, 1);` `      ``// comment out this line and you will see that``      ``// it gives TLE because there is no possible``      ``// output g3.addEdge(0, 3);``      ``g3.printEulerTour();`

## C#

 `// A C# program print Eulerian Trail in a``// given Eulerian or Semi-Eulerian Graph``using` `System;``using` `System.Collections.Generic;` `class` `GFG {``  ` `    ``// A class that represents an undirected graph``    ``class` `Graph {``      ` `        ``// No. of vertices``        ``int` `V;``      ` `        ``// A dynamic array of adjacency lists``        ``List > adj;` `        ``// Constructor``        ``public` `Graph(``int` `V)``        ``{``            ``this``.V = V;``            ``adj = ``new` `List >();` `            ``for` `(``int` `i = 0; i < V; i++) {``                ``adj.Add(``new` `List<``int``>());``            ``}``        ``}` `        ``public` `void` `addEdge(``int` `u, ``int` `v)``        ``{``            ``adj[u].Add(v);``            ``adj[v].Add(u);``        ``}` `        ``// This function removes edge u-v from graph.``        ``// It removes the edge by replacing adjacent``        ``// vertex value with -1.``        ``public` `void` `rmvEdge(``int` `u, ``int` `v)``        ``{``          ` `            ``// Find v in adjacency list of u and replace``            ``// it with -1``            ``int` `iv = adj[u].IndexOf(v);``            ``adj[u][iv] = -1;``          ` `    ``// Find u in adjacency list of v and replace``            ``// it with -1``            ``int` `iu = adj[v].IndexOf(u);``            ``adj[v][iu] = -1;``        ``}` `        ``int` `find(List<``int``> al, ``int` `v)``        ``{``            ``for` `(``int` `i = 0; i < al.Count; i++) {``                ``if` `(al[i] == v) {``                    ``return` `i;``                ``}``            ``}``            ``return` `-1;``        ``}` `        ``// Methods to print Eulerian tour``        ``/* The main function that print Eulerian Trail.``        ``It first finds an odd degree vertex (if there is any)``        ``and then calls printEulerUtil() to print the path */``        ``public` `void` `printEulerTour()``        ``{``          ` `            ``// Find a vertex with odd degree``            ``int` `u = 0;``            ``for` `(``int` `i = 0; i < V; i++) {``                ``if` `(adj[i].Count % 2 == 1) {``                    ``u = i;``                    ``break``;``                ``}``            ``}``          ` `            ``// Print tour starting from oddv``            ``printEulerUtil(u);``            ``Console.WriteLine();``        ``}` `        ``// Print Euler tour starting from vertex u``        ``void` `printEulerUtil(``int` `u)``        ``{``          ` `            ``// Recur for all the vertices adjacent to``            ``// this vertex``            ``for` `(``int` `i = 0; i < adj[u].Count; ++i) {``                ``int` `v = adj[u][i];``              ` `                ``// If edge u-v is not removed and it's a``                ``// valid next edge``                ``if` `(v != -1 && isValidNextEdge(u, v)) {``                    ``Console.Write(u + ``"-"` `+ v + ``" "``);``                    ``rmvEdge(u, v);``                    ``printEulerUtil(v);``                ``}``            ``}``        ``}` `      ` `         ``// This function returns count of vertices``        ``// reachable from v. It does DFS``        ``// A DFS based function to count reachable``        ``// vertices from v``        ``int` `DFSCount(``int` `v, ``bool``[] visited)``        ``{``          ` `            ``// Mark the current node as visited``            ``visited[v] = ``true``;``            ``int` `count = 1;``          ` `            ``// Recur for all vertices adjacent to this vertex``            ``for` `(``int` `i = 0; i < adj[v].Count; ++i) {``                ``int` `u = adj[v][i];` `                ``if` `(u != -1 && !visited[u]) {``                    ``count += DFSCount(u, visited);``                ``}``            ``}``            ``return` `count;``        ``}` `      ` `        ``// Utility function to check if edge u-v``        ``// is a valid next edge in Eulerian trail or circuit``        ``// The function to check if edge u-v can be considered``        ``// as next edge in Euler Tout``        ``bool` `isValidNextEdge(``int` `u, ``int` `v)``        ``{``          ` `            ``// The edge u-v is valid in one of the following``            ``// two cases:``          ` `            ``// 1) If v is the only adjacent vertex of u``            ``int` `count = 0; ``// To store count of adjacent vertices``            ``for` `(``int` `i = 0; i < adj[u].Count; ++i)``                ``if` `(adj[u][i] != -1)``                    ``count++;``            ``if` `(count == 1)``                ``return` `true``;``          ` `             ``// 2) If there are multiple adjacents, then u-v``            ``// is not a bridge``            ``// Do following steps to check if u-v is a bridge` `            ``// 2.a) count of vertices reachable from u``            ``bool``[] visited = ``new` `bool``[V];``            ``Array.Fill(visited, ``false``);``            ``int` `count1 = DFSCount(u, visited);``          ` `            ``// 2.b) Remove edge (u, v) and after removing``            ``// the edge, count vertices reachable from u``            ``rmvEdge(u, v);``            ``Array.Fill(visited, ``false``);``            ``int` `count2 = DFSCount(u, visited);``          ` `            ``// 2.c) Add the edge back to the graph``            ``addEdge(u, v);``          ` `            ``// 2.d) If count1 is greater, then edge (u, v)``            ``// is a bridge``            ``return` `(count1 > count2) ? ``false` `: ``true``;``        ``}``    ``}` `  ` `     ``// Driver program to test above function``    ``public` `static` `void` `Main()``    ``{``      ` `        ``// Let us first create and test``        ``// graphs shown in above figure``        ``Graph g1 = ``new` `Graph(4);``        ``g1.addEdge(0, 1);``        ``g1.addEdge(0, 2);``        ``g1.addEdge(1, 2);``        ``g1.addEdge(2, 3);``        ``g1.printEulerTour();``        ``Graph g3 = ``new` `Graph(4);``        ``g3.addEdge(0, 1);``        ``g3.addEdge(1, 0);``        ``g3.addEdge(0, 2);``        ``g3.addEdge(2, 0);``        ``g3.addEdge(2, 3);``        ``g3.addEdge(3, 1);``      ` `        ``// comment out this line and you will see that``        ``// it gives TLE because there is no possible``        ``// output g3.addEdge(0, 3);``        ``g3.printEulerTour();``    ``}``}``// This code is contributed by Prajwal Kandekar`

Output:

```2-0  0-1  1-2  2-3
1-0  0-2  2-3  3-1  1-0  0-2```

Time Complexity: O(V+E)
The time complexity of the above algorithm is O(V+E) where V is the number of vertices and E is the number of edges in the graph.

Space Complexity: O(V+E)
The space complexity of the above algorithm is O(V+E) where V is the number of vertices and E is the number of edges in the graph.