Consider the following graph:
I'm trying to find a way to enumerate all possible paths from a source node to a target node. For example, from A to E, we have the following possible paths:
A B C D E
A B C E
A C D E
A C E
Note that for A C D E, there are actually 2 paths, since one of the paths uses edge F3 and the other uses edge F5. Also, since there's a cycle between A and C, you could end up with an infinite number of paths, but for the purposes of this I'm only interested in paths in which no node is repeated on the path from source to target.
I wrote a depth first search (DFS) algorithm, but the problem is that when you have multiple edges between 2 nodes (like edges F3 and F5 above) I'm not sure how to handle it. My algorithm only brings back paths A C D E
and A C E
, not the other paths. In the case of A B C E
, I understand the reason, because it starts at A and then goes to C and builds those paths, but when the DFS gets back to node B, it then tries to go to C, but C has already been visited so it stops.
Anyway, I just wondered if there was a way to do this, or maybe this is NP-complete.
In case you'd like to see my DFS, code is below (sorry for the macro abuse, I use these in contest programming so it's a bit of a habit).
#include <algorithm>
#include <numeric>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cassert>
#include <cmath>
#include <complex>
#include <stack>
#include "time.h"
using namespace std;
#define SZ(x) (int)x.size()
#define FOR(i,x,y) for(int i=(int)(x);i<=(int)(y);++i)
#define REP(i,n) FOR(i,0,n-1)
#define FORD(i,x,y) for(int i=(int)(x);i>=(int)(y);--i)
#define ALL(a) (a).begin(),(a).end()
#define FORE(i,t) for(i=t.begin();i!=t.end();++i)
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<bool> VB;
typedef vector<double> VD;
typedef deque<int> DI;
typedef deque<string> DS;
typedef long long i64;
#define PI 3.14159265358979323
#define DEGTORAD(x) (double)x * 3.14159265358979323846264338327950288 / 180.0
#define RADTODEG(x) (double)x * 180 / 3.14159265358979323846264338327950288
#define prt if(1)printf
template <typename T> string tostr(const T& t) { ostringstream os; os<<t; return os.str(); }
typedef pair< char, char > PCC;
map< PCC, int > adj;
map< char, bool > vis;
vector< char > path;
void dfs(char at) {
if (at == 'E') {
REP(i,SZ(path)) {
if (i != 0)
cout<<",";
cout<<path[i];
}
cout<<",E"<<endl;
return;
}
if (vis[at])
return;
vis[at] = true;
map< PCC, int >::iterator it;
FORE(it,adj) {
if (it->first.first == at) {
path.push_back(it->first.first);
dfs(it->first.second);
path.erase(path.end()-1);
}
}
}
int main() {
adj[make_pair('A','B')] = 1;
adj[make_pair('A','C')] = 1;
adj[make_pair('C','D')] = 1;
adj[make_pair('D','E')] = 1;
adj[make_pair('E','I')] = 1;
adj[make_pair('C','F')] = 1;
adj[make_pair('F','G')] = 1;
adj[make_pair('F','H')] = 1;
adj[make_pair('C','E')] = 1;
dfs('A');
return 0;
}
Output:
---------- Capture Output ----------
A,C,D,E
A,C,E