簡體   English   中英

如何返回圖中 2 個節點之間所有可能路徑的二維數組? (C++)

[英]How to return a 2D array of all possible paths between 2 nodes in a graph? (C++)

我從網上獲取了以下代碼,供我用作參考。 int main() {}中,它首先將邊添加到圖中,然后使用調用 function 使用遞歸到output所有可能的路徑。

// 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; 
} 

如何修改此代碼以使 function 返回list<list<int> >而不是打印路徑? 這樣我就可以使用此列表進行進一步處理?

謝謝!

一種方法是通過引用 util function 來傳遞列表。 每當你到達終點時,只需制作一個包含路徑的列表並將其推送到結果列表中。

代碼應如下所示:

// 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&, list<list<int>>&);

public:
    Graph(int V); // Constructor 
    void addEdge(int u, int v);
    list<list<int>> 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' 
list<list<int>> 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;

    list<list<int>> result;

    // Call the recursive helper function to print all paths 
    printAllPathsUtil(s, d, visited, path, path_index, result);

    return result;
}

// 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, list<list<int>>& result)
{
    // 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)
    {
        list<int> tempList;
        for (int i = 0; i < path_index; i++)
            tempList.push_back(path[i]);
        result.push_back(tempList);
    }
    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, result);
    }

    // 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;

    list<list<int>> result = g.printAllPaths(s, d);

    for (auto path : result)
    {
        for (auto node : path)
            std::cout << node << ' ';
        std::cout << std::endl;
    }

    return 0;
}

Output:

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

我不建議使用list 我認為使用std::vector在速度和 memory 方面會更好。 但是由於您要求list ,此代碼返回一個列表。 阿洛斯我不得不說我沒有看代碼,我只是將需要更改的內容更改為返回列表。

這是另一個執行相同操作但使用std::vector的代碼。

#include <iostream>
#include <vector>

class Graph
{
    std::vector<std::vector<int>> graph;
    std::vector<std::vector<int>> paths;
    std::vector<bool> visited;

    void DFS(int currentNode, int destNode, std::vector<int>& currentPath)
    {
        visited[currentNode] = true;
        currentPath.push_back(currentNode);

        if (currentNode == destNode)
            paths.push_back(currentPath);
        else
        {
            for (auto node : graph[currentNode])
                if (!visited[node])
                    DFS(node, destNode, currentPath);
        }

        currentPath.pop_back();
        visited[currentNode] = false;
    }

public:

    Graph(int size)
    {
        graph.resize(size);
        visited.resize(size);
    }

    void addEdge(int from, int to)
    {
        graph[from].push_back(to);
    }

    std::vector<std::vector<int>> GetAllPossiblePaths(int source, int dest)
    {
        paths.clear();
        std::fill(visited.begin(), visited.end(), false);

        std::vector<int> temp;

        DFS(source, dest, temp);

        return paths;
    }
};

int main()
{
    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);

    auto result = g.GetAllPossiblePaths(2, 3);

    for (auto& path : result)
    {
        for (auto node : path)
            std::cout << node << ' ';
        std::cout << std::endl;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM