Open In App

Eulerian Path in undirected graph

Last Updated : 02 Jan, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:  

  1. First, take an empty stack and an empty path.
  2. 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.
  3. 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.
  4. If the current node has not any neighbor then add it to the path and pop stack set current to popped vertex.
  5. Repeat process 3 and 4 until the stack is empty and the current node has not any neighbor.

Eulerian Path in undirected graph

After the process path variable holds the Eulerian path.

Implementation:

C++




// Efficient C++ program to
// find out Eulerian path
#include <bits/stdc++.h>
using namespace std;
 
// Function to find out the path
// It takes the adjacency matrix
// representation of the graph as input
void findpath(int graph[][5], int n)
{
    vector<int> numofadj;
 
    // Find out number of edges each vertex has
    for (int i = 0; i < n; i++)
        numofadj.push_back(accumulate(graph[i],
                                      graph[i] + 5, 0));
 
    // Find out how many vertex has odd number edges
    int startpoint = 0, numofodd = 0;
    for (int i = n - 1; i >= 0; i--)
    {
        if (numofadj[i] % 2 == 1)
        {
            numofodd++;
            startpoint = i;
        }
    }
 
    // If number of vertex with odd number of edges
    // is greater than two return "No Solution".
    if (numofodd > 2)
    {
        cout << "No Solution" << endl;
        return;
    }
 
    // If there is a path find the path
    // Initialize empty stack and path
    // take the starting current as discussed
    stack<int> stack;
    vector<int> path;
    int cur = startpoint;
 
    // Loop will run until there is element in the stack
    // or current edge has some neighbour.
    while (!stack.empty() or
            accumulate(graph[cur],
                       graph[cur] + 5, 0) != 0)
    {
        // If current node has not any neighbour
        // add it to path and pop stack
        // set new current to the popped element
        if (accumulate(graph[cur],
                       graph[cur] + 5, 0) == 0)
        {
            path.push_back(cur);
            cur = stack.top();
            stack.pop();
        }
 
        // If the current vertex has at least one
        // neighbour add the current vertex to stack,
        // remove the edge between them and set the
        // current to its neighbour.
        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;
                }
            }
        }
    }
 
    // print the path
    for (auto ele : path) cout << ele << " -> ";
    cout << cur << endl;
}
 
// Driver Code
int main()
{
    // Test case 1
    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);
 
    // Test case 2
    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);
 
    // Test case 3
    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;
}
 
// This code is contributed by
// sanjeev2552


Java




// Efficient Java program to
// find out Eulerian path
import java.util.*;
 
class GFG
{
 
    // Function to find out the path
    // It takes the adjacency matrix
    // representation of the graph as input
    static void findpath(int[][] graph, int n)
    {
        Vector<Integer> numofadj = new Vector<>();
 
        // Find out number of edges each vertex has
        for (int i = 0; i < n; i++)
            numofadj.add(accumulate(graph[i], 0));
 
        // Find out how many vertex has odd number edges
        int startPoint = 0, numofodd = 0;
        for (int i = n - 1; i >= 0; i--)
        {
            if (numofadj.elementAt(i) % 2 == 1)
            {
                numofodd++;
                startPoint = i;
            }
        }
 
        // If number of vertex with odd number of edges
        // is greater than two return "No Solution".
        if (numofodd > 2)
        {
            System.out.println("No Solution");
            return;
        }
 
        // If there is a path find the path
        // Initialize empty stack and path
        // take the starting current as discussed
        Stack<Integer> stack = new Stack<>();
        Vector<Integer> path = new Vector<>();
        int cur = startPoint;
 
        // Loop will run until there is element in the stack
        // or current edge has some neighbour.
        while (!stack.isEmpty() || accumulate(graph[cur], 0) != 0)
        {
 
            // If current node has not any neighbour
            // add it to path and pop stack
            // set new current to the popped element
            if (accumulate(graph[cur], 0) == 0)
            {
                path.add(cur);
                cur = stack.pop();
 
                // If the current vertex has at least one
                // neighbour add the current vertex to stack,
                // remove the edge between them and set the
                // current to its neighbour.
            }
            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;
                    }
                }
            }
        }
 
        // print the path
        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;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        // Test case 1
        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);
 
        // Test case 2
        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);
 
        // Test case 3
        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);
    }
}
 
// This code is contributed by
// sanjeev2552


Python3




# Efficient Python3 program to
# find out Eulerian path
 
# Function to find out the path
# It takes the adjacency matrix
# representation of the graph as input
def findpath(graph, n):
     
    numofadj = []
 
    # Find out number of edges each
    # vertex has
    for i in range(n):
        numofadj.append(sum(graph[i]))
 
    # Find out how many vertex has
    # odd number edges
    startpoint, numofodd = 0, 0
    for i in range(n - 1, -1, -1):
        if (numofadj[i] % 2 == 1):
            numofodd += 1
            startpoint = i
 
    # If number of vertex with odd number of edges
    # is greater than two return "No Solution".
    if (numofodd > 2):
        print("No Solution")
        return
 
    # If there is a path find the path
    # Initialize empty stack and path
    # take the starting current as discussed
    stack = []
    path = []
    cur = startpoint
 
    # Loop will run until there is element in the
    # stack or current edge has some neighbour.
    while (len(stack) > 0 or sum(graph[cur])!= 0):
         
        # If current node has not any neighbour
        # add it to path and pop stack set new
        # current to the popped element
        if (sum(graph[cur]) == 0):
            path.append(cur)
            cur = stack[-1]
            del stack[-1]
 
        # If the current vertex has at least one
        # neighbour add the current vertex to stack,
        # remove the edge between them and set the
        # current to its neighbour.
        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
 
    # Print the path
    for ele in path:
        print(ele, end = " -> ")
         
    print(cur)
 
# Driver Code
if __name__ == '__main__':
     
    # Test case 1
    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)
 
    # Test case 2
    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)
 
    # Test case 3
    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)
 
# This code is contributed by mohit kumar 29


C#




// Efficient C# program to
// find out Eulerian path
using System;
using System.Collections.Generic;
class GFG{
 
// Function to find out the path
// It takes the adjacency matrix
// representation of the graph
// as input
static void findpath(int[,] graph,
                     int n)
{
  List<int> numofadj =
            new List<int>();
 
  // Find out number of edges
  // each vertex has
  for (int i = 0; i < n; i++)
    numofadj.Add(accumulate(graph,
                            i, 0));
 
  // Find out how many vertex has
  // odd number edges
  int startPoint = 0, numofodd = 0;
  for (int i = n - 1; i >= 0; i--)
  {
    if (numofadj[i] % 2 == 1)
    {
      numofodd++;
      startPoint = i;
    }
  }
 
  // If number of vertex with odd
  // number of edges is greater than
  // two return "No Solution".
  if (numofodd > 2)
  {
    Console.WriteLine("No Solution");
    return;
  }
 
  // If there is a path find the path
  // Initialize empty stack and path
  // take the starting current as
  // discussed
  Stack<int> stack = new Stack<int>();
  List<int> path = new List<int>();
  int cur = startPoint;
 
  // Loop will run until there is element
  // in the stack or current edge has some
  // neighbour.
  while (stack.Count != 0 ||
         accumulate(graph, cur, 0) != 0)
  {
 
    // If current node has not any
    // neighbour add it to path and
    // pop stack set new current to
    // the popped element
    if (accumulate(graph,cur, 0) == 0)
    {
      path.Add(cur);
      cur = stack.Pop();
 
      // If the current vertex has at
      // least one neighbour add the
      // current vertex to stack, remove
      // the edge between them and set the
      // current to its neighbour.
    }
    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;
        }
      }
    }
  }
 
  // print the path
  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;
}
   
// Driver Code
public static void Main(String[] args)
{
  // Test case 1
  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);
 
  // Test case 2
  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);
 
  // Test case 3
  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);
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
 
// Efficient JavaScript program to
// find out Eulerian path
 
// Function to find out the path
// It takes the adjacency matrix
// representation of the graph as input
 
function sum(a){
    let Sum = 0
    for(let x of a)
        Sum += x
    return Sum
}
 
function findpath(graph, n){
     
    let numofadj = []
 
    // Find out number of edges each
    // vertex has
    for(let i=0;i<n;i++)
        numofadj.push(sum(graph[i]))
 
    // Find out how many vertex has
    // odd number edges
    let startpoint = 0, numofodd = 0
    for(let i=n-1;i>=0;i--){
        if (numofadj[i] % 2 == 1){
            numofodd += 1
            startpoint = i
        }
    }
 
    // If number of vertex with odd number of edges
    // is greater than two return "No Solution".
    if (numofodd > 2){
        document.write("No Solution","</br>")
        return
    }
 
    // If there is a path find the path
    // Initialize empty stack and path
    // take the starting current as discussed
    let stack = []
    let path = []
    let cur = startpoint
 
    // Loop will run until there is element in the
    // stack or current edge has some neighbour.
    while (stack.length > 0 || sum(graph[cur])!= 0){
         
        // If current node has not any neighbour
        // add it to path and pop stack set new
        // current to the popped element
        if (sum(graph[cur]) == 0){
            path.push(cur)
            cur = stack.pop()
        }
 
        // If the current vertex has at least one
        // neighbour add the current vertex to stack,
        // remove the edge between them and set the
        // current to its neighbour.
        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
                }
            }
        }
    }
    // Print the path
    for(let ele of path)
        document.write(ele," -> ")
         
    document.write(cur,"</br>")
}
 
// Driver Code
     
// Test case 1
 
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)
 
// Test case 2
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)
 
// Test case 3
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)
 
// This code is contributed by shinjanpatra
 
</script>


Output

4 -> 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)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads