This problem is different from traditional BFS or DFS search, as the previously visited node can be visited again, as they are on different paths.
Therefore, we only need to keep a visited hash set for the current path (from the start node to the current node).
We introduce three methods.
1. DFS recursive method.
2. DFS iterative method using stack.
3. BFS method.
1. DFS Recursive
#include <iostream>
#include <vector>
#include <stack>
#include <unordered_set>
using namespace std;
struct GraphNode
{
int label;
vector<GraphNode*> adjs;
GraphNode(int x): label(x){}
};
void allSimplePathDFSRecursive(GraphNode *start, GraphNode *end, vector<GraphNode*> &path, vector<vector<GraphNode*> > &result, unordered_set<GraphNode*> &hash)
{
//cout << start->label << endl;
if(start == end)
{
result.push_back(path);
}
else
{
for(int i=0; i<start->adjs.size(); i++)
{
if(hash.count(start->adjs[i])==0)
{
hash.insert(start->adjs[i]);
path.push_back(start->adjs[i]);
allSimplePathDFSRecursive(start->adjs[i], end, path, result, hash);
hash.erase(start->adjs[i]);
path.pop_back();
}
}
}
}
int main() {
GraphNode *n0 = new GraphNode(0);
GraphNode *n1 = new GraphNode(1);
GraphNode *n2 = new GraphNode(2);
GraphNode *n3 = new GraphNode(3);
GraphNode *n4 = new GraphNode(4);
GraphNode *n5 = new GraphNode(5);
n0->adjs.push_back(n1);
n0->adjs.push_back(n2);
n0->adjs.push_back(n5);
n1->adjs.push_back(n0);
n1->adjs.push_back(n2);
n2->adjs.push_back(n0);
n2->adjs.push_back(n1);
n2->adjs.push_back(n3);
n2->adjs.push_back(n4);
n3->adjs.push_back(n2);
n3->adjs.push_back(n4);
n3->adjs.push_back(n5);
n4->adjs.push_back(n2);
n4->adjs.push_back(n3);
n5->adjs.push_back(n0);
n5->adjs.push_back(n3);
vector<vector<GraphNode*> > res;
vector<GraphNode*> path;
unordered_set<GraphNode*> hash;
hash.insert(n0);
path.push_back(n0);
allSimplePathDFSRecursive(n0, n5, path, res, hash);
for(int i=0; i<res.size(); i++)
{
for(int j=0; j<res[i].size(); j++)
{
cout << res[i][j]->label << " ";
}
cout << endl;
}
return 0;
}
2. DFS Iterative
no path vector required.
#include <iostream>
#include <vector>
#include <stack>
#include <unordered_set>
using namespace std;
struct GraphNode
{
<span style="white-space:pre"> </span>int label;
<span style="white-space:pre"> </span>vector<GraphNode*> adjs;
<span style="white-space:pre"> </span>GraphNode(int x): label(x){}
};
typedef vector<GraphNode*>::iterator adj_iter;
vector<int> genPath(vector<pair<GraphNode*,adj_iter> > &stack)
{
<span style="white-space:pre"> </span>vector<int> result;
<span style="white-space:pre"> </span>for(int i=0; i<stack.size(); i++)
<span style="white-space:pre"> </span>result.push_back(stack[i].first->label);
<span style="white-space:pre"> </span>return result;
}
vector<vector<int> > allSimplePathDFSIterative(GraphNode *start, GraphNode *end)
{
<span style="white-space:pre"> </span>vector<vector<int> > result;
<span style="white-space:pre"> </span>vector<pair<GraphNode*,adj_iter> > stack;
<span style="white-space:pre"> </span>unordered_set<GraphNode*> hash;
<span style="white-space:pre"> </span>stack.push_back(make_pair(start, start->adjs.begin()));
<span style="white-space:pre"> </span>while(!stack.empty())
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>GraphNode *cur = stack.back().first;
<span style="white-space:pre"> </span>adj_iter iter = stack.back().second;
<span style="white-space:pre"> </span>if(iter == cur->adjs.begin())
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>hash.insert(cur);
<span style="white-space:pre"> </span>if(cur == end)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>vector<int> res = genPath(stack);
<span style="white-space:pre"> </span>result.push_back(res);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(iter != cur->adjs.end())
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>GraphNode *next = *iter;
<span style="white-space:pre"> </span>stack.back().second = ++iter;
<span style="white-space:pre"> </span>if(hash.count(next) == 0)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>stack.push_back(make_pair(next, next->adjs.begin()));
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>hash.erase(stack.back().first);
<span style="white-space:pre"> </span>stack.pop_back();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return result;
}
int main() {
<span style="white-space:pre"> </span>GraphNode *n0 = new GraphNode(0);
<span style="white-space:pre"> </span>GraphNode *n1 = new GraphNode(1);
<span style="white-space:pre"> </span>GraphNode *n2 = new GraphNode(2);
<span style="white-space:pre"> </span>GraphNode *n3 = new GraphNode(3);
<span style="white-space:pre"> </span>GraphNode *n4 = new GraphNode(4);
<span style="white-space:pre"> </span>GraphNode *n5 = new GraphNode(5);
<span style="white-space:pre"> </span>n0->adjs.push_back(n1);
<span style="white-space:pre"> </span>n0->adjs.push_back(n2);
<span style="white-space:pre"> </span>n0->adjs.push_back(n5);
<span style="white-space:pre"> </span>n1->adjs.push_back(n0);
<span style="white-space:pre"> </span>n1->adjs.push_back(n2);
<span style="white-space:pre"> </span>n2->adjs.push_back(n0);
<span style="white-space:pre"> </span>n2->adjs.push_back(n1);
<span style="white-space:pre"> </span>n2->adjs.push_back(n3);
<span style="white-space:pre"> </span>n2->adjs.push_back(n4);
<span style="white-space:pre"> </span>n3->adjs.push_back(n2);
<span style="white-space:pre"> </span>n3->adjs.push_back(n4);
<span style="white-space:pre"> </span>n3->adjs.push_back(n5);
<span style="white-space:pre"> </span>n4->adjs.push_back(n2);
<span style="white-space:pre"> </span>n4->adjs.push_back(n3);
<span style="white-space:pre"> </span>n5->adjs.push_back(n0);
<span style="white-space:pre"> </span>n5->adjs.push_back(n3);
<span style="white-space:pre"> </span>vector<vector<int> > res = allSimplePathDFSIterative(n0, n5);
<span style="white-space:pre"> </span>for(int i=0; i<res.size(); i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>for(int j=0; j<res[i].size(); j++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>cout << res[i][j] << " ";
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>cout << endl;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>return 0;
}