Imprime todas las rutas desde un origen determinado hasta un destino

Dado un gráfico dirigido, un vértice de origen ‘s’ y un vértice de destino ‘d’, imprima todas las rutas desde la ‘s’ dada hasta la ‘d’. 
Considere el siguiente gráfico dirigido. Sea s 2 y d 3. Hay 3 caminos diferentes de 2 a 3.
 

allPaths

Acercarse:

  1. La idea es hacer el primer recorrido en profundidad de un gráfico dirigido dado.
  2. Inicie el recorrido DFS desde el origen.
  3. Siga almacenando los vértices visitados en una array o HashMap diga ‘ruta []’.
  4. Si se alcanza el vértice de destino, imprime el contenido de ruta[].
  5. Lo importante es marcar los vértices actuales en el camino [] como visitados también para que el recorrido no vaya en un ciclo.

A continuación se muestra la implementación de la idea anterior.

C++14

// C++ program to print all paths
// from a source to destination.
#include <iostream>
#include <list>
using namespace std;
 
// A directed graph using
// adjacency list representation
class Graph {
    int V; // No. of vertices in graph
    list<int>* adj; // Pointer to an array containing
                    // adjacency lists
 
    // A recursive function used by printAllPaths()
    void printAllPathsUtil(int, int, bool[], int[], int&);
 
public:
    Graph(int V); // Constructor
    void addEdge(int u, int v);
    void printAllPaths(int s, int d);
};
 
Graph::Graph(int V)
{
    this->V = V;
    adj = new list<int>[V];
}
 
void Graph::addEdge(int u, int v)
{
    adj[u].push_back(v); // Add v to u’s list.
}
 
// Prints all paths from 's' to 'd'
void Graph::printAllPaths(int s, int d)
{
    // Mark all the vertices as not visited
    bool* visited = new bool[V];
 
    // Create an array to store paths
    int* path = new int[V];
    int path_index = 0; // Initialize path[] as empty
 
    // Initialize all vertices as not visited
    for (int i = 0; i < V; i++)
        visited[i] = false;
 
    // Call the recursive helper function to print all paths
    printAllPathsUtil(s, d, visited, path, path_index);
}
 
// A recursive function to print all paths from 'u' to 'd'.
// visited[] keeps track of vertices in current path.
// path[] stores actual vertices and path_index is current
// index in path[]
void Graph::printAllPathsUtil(int u, int d, bool visited[],
                              int path[], int& path_index)
{
    // Mark the current node and store it in path[]
    visited[u] = true;
    path[path_index] = u;
    path_index++;
 
    // If current vertex is same as destination, then print
    // current path[]
    if (u == d) {
        for (int i = 0; i < path_index; i++)
            cout << path[i] << " ";
        cout << endl;
    }
    else // If current vertex is not destination
    {
        // Recur for all the vertices adjacent to current
        // vertex
        list<int>::iterator i;
        for (i = adj[u].begin(); i != adj[u].end(); ++i)
            if (!visited[*i])
                printAllPathsUtil(*i, d, visited, path,
                                  path_index);
    }
 
    // Remove current vertex from path[] and mark it as
    // unvisited
    path_index--;
    visited[u] = false;
}
 
// Driver program
int main()
{
    // Create a graph given in the above diagram
    Graph g(4);
    g.addEdge(0, 1);
    g.addEdge(0, 2);
    g.addEdge(0, 3);
    g.addEdge(2, 0);
    g.addEdge(2, 1);
    g.addEdge(1, 3);
 
    int s = 2, d = 3;
    cout << "Following are all different paths from " << s
         << " to " << d << endl;
    g.printAllPaths(s, d);
 
    return 0;
}

Java

// JAVA program to print all
// paths from a source to
// destination.
import java.util.ArrayList;
import java.util.List;
 
// A directed graph using
// adjacency list representation
public class Graph {
 
    // No. of vertices in graph
    private int v;
 
    // adjacency list
    private ArrayList<Integer>[] adjList;
 
    // Constructor
    public Graph(int vertices)
    {
 
        // initialise vertex count
        this.v = vertices;
 
        // initialise adjacency list
        initAdjList();
    }
 
    // utility method to initialise
    // adjacency list
    @SuppressWarnings("unchecked")
    private void initAdjList()
    {
        adjList = new ArrayList[v];
 
        for (int i = 0; i < v; i++) {
            adjList[i] = new ArrayList<>();
        }
    }
 
    // add edge from u to v
    public void addEdge(int u, int v)
    {
        // Add v to u's list.
        adjList[u].add(v);
    }
 
    // Prints all paths from
    // 's' to 'd'
    public void printAllPaths(int s, int d)
    {
        boolean[] isVisited = new boolean[v];
        ArrayList<Integer> pathList = new ArrayList<>();
 
        // add source to path[]
        pathList.add(s);
 
        // Call recursive utility
        printAllPathsUtil(s, d, isVisited, pathList);
    }
 
    // A recursive function to print
    // all paths from 'u' to 'd'.
    // isVisited[] keeps track of
    // vertices in current path.
    // localPathList<> stores actual
    // vertices in the current path
    private void printAllPathsUtil(Integer u, Integer d,
                                   boolean[] isVisited,
                                   List<Integer> localPathList)
    {
 
        if (u.equals(d)) {
            System.out.println(localPathList);
            // if match found then no need to traverse more till depth
            return;
        }
 
        // Mark the current node
        isVisited[u] = true;
 
        // Recur for all the vertices
        // adjacent to current vertex
        for (Integer i : adjList[u]) {
            if (!isVisited[i]) {
                // store current node
                // in path[]
                localPathList.add(i);
                printAllPathsUtil(i, d, isVisited, localPathList);
 
                // remove current node
                // in path[]
                localPathList.remove(i);
            }
        }
 
        // Mark the current node
        isVisited[u] = false;
    }
 
    // Driver program
    public static void main(String[] args)
    {
        // Create a sample graph
        Graph g = new Graph(4);
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(0, 3);
        g.addEdge(2, 0);
        g.addEdge(2, 1);
        g.addEdge(1, 3);
 
        // arbitrary source
        int s = 2;
 
        // arbitrary destination
        int d = 3;
 
        System.out.println(
            "Following are all different paths from "
            + s + " to " + d);
        g.printAllPaths(s, d);
    }
}
 
// This code is contributed by Himanshu Shekhar.

Python3

# Python program to print all paths from a source to destination.
  
from collections import defaultdict
  
# This class represents a directed graph
# using adjacency list representation
class Graph:
  
    def __init__(self, vertices):
        # No. of vertices
        self.V = vertices
         
        # default dictionary to store graph
        self.graph = defaultdict(list)
  
    # function to add an edge to graph
    def addEdge(self, u, v):
        self.graph[u].append(v)
  
    '''A recursive function to print all paths from 'u' to 'd'.
    visited[] keeps track of vertices in current path.
    path[] stores actual vertices and path_index is current
    index in path[]'''
    def printAllPathsUtil(self, u, d, visited, path):
 
        # Mark the current node as visited and store in path
        visited[u]= True
        path.append(u)
 
        # If current vertex is same as destination, then print
        # current path[]
        if u == d:
            print (path)
        else:
            # If current vertex is not destination
            # Recur for all the vertices adjacent to this vertex
            for i in self.graph[u]:
                if visited[i]== False:
                    self.printAllPathsUtil(i, d, visited, path)
                     
        # Remove current vertex from path[] and mark it as unvisited
        path.pop()
        visited[u]= False
  
  
    # Prints all paths from 's' to 'd'
    def printAllPaths(self, s, d):
 
        # Mark all the vertices as not visited
        visited =[False]*(self.V)
 
        # Create an array to store paths
        path = []
 
        # Call the recursive helper function to print all paths
        self.printAllPathsUtil(s, d, visited, path)
  
  
  
# Create a graph given in the above diagram
g = Graph(4)
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(0, 3)
g.addEdge(2, 0)
g.addEdge(2, 1)
g.addEdge(1, 3)
  
s = 2 ; d = 3
print ("Following are all different paths from % d to % d :" %(s, d))
g.printAllPaths(s, d)
# This code is contributed by Neelam Yadav

C#

// C# program to print all
// paths from a source to
// destination.
using System;
using System.Collections.Generic;
 
// A directed graph using
// adjacency list representation
public class Graph {
 
    // No. of vertices in graph
    private int v;
 
    // adjacency list
    private List<int>[] adjList;
 
    // Constructor
    public Graph(int vertices)
    {
 
        // initialise vertex count
        this.v = vertices;
 
        // initialise adjacency list
        initAdjList();
    }
 
    // utility method to initialise
    // adjacency list
    private void initAdjList()
    {
        adjList = new List<int>[v];
 
        for (int i = 0; i < v; i++) {
            adjList[i] = new List<int>();
        }
    }
 
    // add edge from u to v
    public void addEdge(int u, int v)
    {
        // Add v to u's list.
        adjList[u].Add(v);
    }
 
    // Prints all paths from
    // 's' to 'd'
    public void printAllPaths(int s, int d)
    {
        bool[] isVisited = new bool[v];
        List<int> pathList = new List<int>();
 
        // add source to path[]
        pathList.Add(s);
 
        // Call recursive utility
        printAllPathsUtil(s, d, isVisited, pathList);
    }
 
    // A recursive function to print
    // all paths from 'u' to 'd'.
    // isVisited[] keeps track of
    // vertices in current path.
    // localPathList<> stores actual
    // vertices in the current path
    private void printAllPathsUtil(int u, int d,
                                   bool[] isVisited,
                                   List<int> localPathList)
    {
 
        if (u.Equals(d)) {
            Console.WriteLine(string.Join(" ", localPathList));
            // if match found then no need
            // to traverse more till depth
            return;
        }
 
        // Mark the current node
        isVisited[u] = true;
 
        // Recur for all the vertices
        // adjacent to current vertex
        foreach(int i in adjList[u])
        {
            if (!isVisited[i]) {
                // store current node
                // in path[]
                localPathList.Add(i);
                printAllPathsUtil(i, d, isVisited,
                                  localPathList);
 
                // remove current node
                // in path[]
                localPathList.Remove(i);
            }
        }
 
        // Mark the current node
        isVisited[u] = false;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        // Create a sample graph
        Graph g = new Graph(4);
        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(0, 3);
        g.addEdge(2, 0);
        g.addEdge(2, 1);
        g.addEdge(1, 3);
 
        // arbitrary source
        int s = 2;
 
        // arbitrary destination
        int d = 3;
 
        Console.WriteLine("Following are all different"
                          + " paths from " + s + " to " + d);
        g.printAllPaths(s, d);
    }
}
 
// This code contributed by Rajput-Ji

Javascript

<script>
 
// JavaScript program to print all
// paths from a source to
// destination.
 
let  v;
 
let adjList;
 
// A directed graph using
// adjacency list representation
function Graph(vertices)
{
    // initialise vertex count
        v = vertices;
  
        // initialise adjacency list
        initAdjList();
}
 
// utility method to initialise
    // adjacency list
function initAdjList()
{
    adjList = new Array(v);
  
        for (let i = 0; i < v; i++) {
            adjList[i] = [];
        }
}
 
// add edge from u to v
function addEdge(u,v)
{
    // Add v to u's list.
        adjList[u].push(v);
}
 
// Prints all paths from
    // 's' to 'd'
function printAllPaths(s,d)
{
     let isVisited = new Array(v);
     for(let i=0;i<v;i++)
         isVisited[i]=false;
        let pathList = [];
  
        // add source to path[]
        pathList.push(s);
  
        // Call recursive utility
        printAllPathsUtil(s, d, isVisited, pathList);
}
 
// A recursive function to print
    // all paths from 'u' to 'd'.
    // isVisited[] keeps track of
    // vertices in current path.
    // localPathList<> stores actual
    // vertices in the current path
function printAllPathsUtil(u,d,isVisited,localPathList)
{
    if (u == (d)) {
            document.write(localPathList+"<br>");
            // if match found then no need to
            // traverse more till depth
            return;
        }
  
        // Mark the current node
        isVisited[u] = true;
  
        // Recur for all the vertices
        // adjacent to current vertex
        for (let i=0;i< adjList[u].length;i++) {
            if (!isVisited[adjList[u][i]]) {
                // store current node
                // in path[]
                localPathList.push(adjList[u][i]);
                printAllPathsUtil(adjList[u][i], d,
                isVisited, localPathList);
  
                // remove current node
                // in path[]
                localPathList.splice(localPathList.indexOf
                (adjList[u][i]),1);
            }
        }
  
        // Mark the current node
        isVisited[u] = false;
}
 
 // Driver program
// Create a sample graph
Graph(4);
addEdge(0, 1);
addEdge(0, 2);
addEdge(0, 3);
addEdge(2, 0);
addEdge(2, 1);
addEdge(1, 3);
 
// arbitrary source
let s = 2;
 
// arbitrary destination
let d = 3;
 
document.write(
"Following are all different paths from "
+ s + " to " + d+"<Br>");
printAllPaths(s, d);
     
 
 
// This code is contributed by avanitrachhadiya2155
 
</script>
Producción

Following are all different paths from 2 to 3
2 0 1 3 
2 0 3 
2 1 3 

Análisis de Complejidad: 

  • Complejidad de tiempo: O(V^V), La complejidad de tiempo es exponencial. De cada vértice hay v vértices que se pueden visitar desde el vértice actual.
  • Espacio auxiliar: O(V^V), Para almacenar las rutas se necesita espacio V^V.

Este artículo es una contribución de Shivam Gupta . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *