Given an adjacency matrix representation of an undirected graph. Find if there is any Eulerian Path in the graph. If there is no path print “No Solution”. If there is any path print the path.
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"
The base case of this problem is if the number of vertices with an odd number of edges(i.e. odd degree) is greater than 2 then there is no Eulerian path.
If it has the solution and all the nodes have an even number of edges then we can start our path from any of the nodes.
If it has the solution and exactly two vertices have an odd number of edges then we have to start our path from one of these two vertices.
There will not be the case where exactly one vertex has an odd number of edges, as there is an even number of edges in total.
The process to Find the Path:
- First, take an empty stack and an empty path.
- If all the vertices have an even number of edges then start from any of them. If two of the vertices have an odd number of edges then start from one of them. Set variable current to this starting vertex.
- If the current vertex has at least one adjacent node then first discover that node and then discover the current node by backtracking. To do so add the current node to stack, remove the edge between the current node and neighbor node, set current to the neighbor node.
- If the current node has not any neighbor then add it to the path and pop stack set current to popped vertex.
- Repeat process 3 and 4 until the stack is empty and the current node has not any neighbor.

After the process path variable holds the Eulerian path.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
void findpath( int graph[][5], int n)
{
vector< int > numofadj;
for ( int i = 0; i < n; i++)
numofadj.push_back(accumulate(graph[i],
graph[i] + 5, 0));
int startpoint = 0, numofodd = 0;
for ( int i = n - 1; i >= 0; i--)
{
if (numofadj[i] % 2 == 1)
{
numofodd++;
startpoint = i;
}
}
if (numofodd > 2)
{
cout << "No Solution" << endl;
return ;
}
stack< int > stack;
vector< int > path;
int cur = startpoint;
while (!stack.empty() or
accumulate(graph[cur],
graph[cur] + 5, 0) != 0)
{
if (accumulate(graph[cur],
graph[cur] + 5, 0) == 0)
{
path.push_back(cur);
cur = stack.top();
stack.pop();
}
else
{
for ( int i = 0; i < n; i++)
{
if (graph[cur][i] == 1)
{
stack.push(cur);
graph[cur][i] = 0;
graph[i][cur] = 0;
cur = i;
break ;
}
}
}
}
for ( auto ele : path) cout << ele << " -> " ;
cout << cur << endl;
}
int main()
{
int graph1[][5] = {{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}};
int n = sizeof (graph1) / sizeof (graph1[0]);
findpath(graph1, n);
int graph2[][5] = {{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}};
n = sizeof (graph1) / sizeof (graph1[0]);
findpath(graph2, n);
int graph3[][5] = {{0, 1, 0, 0, 1},
{1, 0, 1, 1, 1},
{0, 1, 0, 1, 0},
{0, 1, 1, 0, 1},
{1, 1, 0, 1, 0}};
n = sizeof (graph1) / sizeof (graph1[0]);
findpath(graph3, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static void findpath( int [][] graph, int n)
{
Vector<Integer> numofadj = new Vector<>();
for ( int i = 0 ; i < n; i++)
numofadj.add(accumulate(graph[i], 0 ));
int startPoint = 0 , numofodd = 0 ;
for ( int i = n - 1 ; i >= 0 ; i--)
{
if (numofadj.elementAt(i) % 2 == 1 )
{
numofodd++;
startPoint = i;
}
}
if (numofodd > 2 )
{
System.out.println( "No Solution" );
return ;
}
Stack<Integer> stack = new Stack<>();
Vector<Integer> path = new Vector<>();
int cur = startPoint;
while (!stack.isEmpty() || accumulate(graph[cur], 0 ) != 0 )
{
if (accumulate(graph[cur], 0 ) == 0 )
{
path.add(cur);
cur = stack.pop();
}
else
{
for ( int i = 0 ; i < n; i++)
{
if (graph[cur][i] == 1 )
{
stack.add(cur);
graph[cur][i] = 0 ;
graph[i][cur] = 0 ;
cur = i;
break ;
}
}
}
}
for ( int ele : path)
System.out.print(ele + " -> " );
System.out.println(cur);
}
static int accumulate( int [] arr, int sum)
{
for ( int i : arr)
sum += i;
return sum;
}
public static void main(String[] args)
{
int [][] graph1 = { { 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 } };
int n = graph1.length;
findpath(graph1, n);
int [][] graph2 = { { 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 } };
n = graph2.length;
findpath(graph2, n);
int [][] graph3 = { { 0 , 1 , 0 , 0 , 1 },
{ 1 , 0 , 1 , 1 , 1 },
{ 0 , 1 , 0 , 1 , 0 },
{ 0 , 1 , 1 , 0 , 1 },
{ 1 , 1 , 0 , 1 , 0 } };
n = graph3.length;
findpath(graph3, n);
}
}
|
Python3
def findpath(graph, n):
numofadj = []
for i in range (n):
numofadj.append( sum (graph[i]))
startpoint, numofodd = 0 , 0
for i in range (n - 1 , - 1 , - 1 ):
if (numofadj[i] % 2 = = 1 ):
numofodd + = 1
startpoint = i
if (numofodd > 2 ):
print ( "No Solution" )
return
stack = []
path = []
cur = startpoint
while ( len (stack) > 0 or sum (graph[cur])! = 0 ):
if ( sum (graph[cur]) = = 0 ):
path.append(cur)
cur = stack[ - 1 ]
del stack[ - 1 ]
else :
for i in range (n):
if (graph[cur][i] = = 1 ):
stack.append(cur)
graph[cur][i] = 0
graph[i][cur] = 0
cur = i
break
for ele in path:
print (ele, end = " -> " )
print (cur)
if __name__ = = '__main__' :
graph1 = [ [ 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 ] ]
n = len (graph1)
findpath(graph1, n)
graph2 = [ [ 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 ] ]
n = len (graph2)
findpath(graph2, n)
graph3 = [ [ 0 , 1 , 0 , 0 , 1 ],
[ 1 , 0 , 1 , 1 , 1 ],
[ 0 , 1 , 0 , 1 , 0 ],
[ 0 , 1 , 1 , 0 , 1 ],
[ 1 , 1 , 0 , 1 , 0 ] ]
n = len (graph3)
findpath(graph3, n)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void findpath( int [,] graph,
int n)
{
List< int > numofadj =
new List< int >();
for ( int i = 0; i < n; i++)
numofadj.Add(accumulate(graph,
i, 0));
int startPoint = 0, numofodd = 0;
for ( int i = n - 1; i >= 0; i--)
{
if (numofadj[i] % 2 == 1)
{
numofodd++;
startPoint = i;
}
}
if (numofodd > 2)
{
Console.WriteLine( "No Solution" );
return ;
}
Stack< int > stack = new Stack< int >();
List< int > path = new List< int >();
int cur = startPoint;
while (stack.Count != 0 ||
accumulate(graph, cur, 0) != 0)
{
if (accumulate(graph,cur, 0) == 0)
{
path.Add(cur);
cur = stack.Pop();
}
else
{
for ( int i = 0; i < n; i++)
{
if (graph[cur, i] == 1)
{
stack.Push(cur);
graph[cur, i] = 0;
graph[i, cur] = 0;
cur = i;
break ;
}
}
}
}
foreach ( int ele in path)
Console.Write(ele + " -> " );
Console.WriteLine(cur);
}
static int accumulate( int [,] matrix,
int row, int sum)
{
int []arr = GetRow(matrix,
row);
foreach ( int i in arr)
sum += i;
return sum;
}
public static int [] GetRow( int [,] matrix,
int row)
{
var rowLength = matrix.GetLength(1);
var rowVector = new int [rowLength];
for ( var i = 0; i < rowLength; i++)
rowVector[i] = matrix[row, i];
return rowVector;
}
public static void Main(String[] args)
{
int [,] graph1 = {{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}};
int n = graph1.GetLength(0);
findpath(graph1, n);
int [,] graph2 = {{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}};
n = graph2.GetLength(0);
findpath(graph2, n);
int [,] graph3 = {{0, 1, 0, 0, 1},
{1, 0, 1, 1, 1},
{0, 1, 0, 1, 0},
{0, 1, 1, 0, 1},
{1, 1, 0, 1, 0}};
n = graph3.GetLength(0);
findpath(graph3, n);
}
}
|
Javascript
<script>
function sum(a){
let Sum = 0
for (let x of a)
Sum += x
return Sum
}
function findpath(graph, n){
let numofadj = []
for (let i=0;i<n;i++)
numofadj.push(sum(graph[i]))
let startpoint = 0, numofodd = 0
for (let i=n-1;i>=0;i--){
if (numofadj[i] % 2 == 1){
numofodd += 1
startpoint = i
}
}
if (numofodd > 2){
document.write( "No Solution" , "</br>" )
return
}
let stack = []
let path = []
let cur = startpoint
while (stack.length > 0 || sum(graph[cur])!= 0){
if (sum(graph[cur]) == 0){
path.push(cur)
cur = stack.pop()
}
else {
for (let i=0;i<n;i++){
if (graph[cur][i] == 1){
stack.push(cur)
graph[cur][i] = 0
graph[i][cur] = 0
cur = i
break
}
}
}
}
for (let ele of path)
document.write(ele, " -> " )
document.write(cur, "</br>" )
}
let graph1 = [ [ 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 ] ]
let n = graph1.length
findpath(graph1, n)
let graph2 = [ [ 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 ] ]
n = graph2.length
findpath(graph2, n)
let graph3 = [ [ 0, 1, 0, 0, 1 ],
[ 1, 0, 1, 1, 1 ],
[ 0, 1, 0, 1, 0 ],
[ 0, 1, 1, 0, 1 ],
[ 1, 1, 0, 1, 0 ] ]
n = graph3.length
findpath(graph3, n)
</script>
|
Output4 -> 0 -> 1 -> 3 -> 2 -> 1
No Solution
4 -> 3 -> 2 -> 1 -> 4 -> 0 -> 1 -> 3
Time Complexity: The runtime complexity of this algorithm is O(E). This algorithm can also be used to find the Eulerian circuit. If the first and last vertex of the path is the same then it will be an Eulerian circuit.
Auxiliary Space: O(n)