Considere el siguiente gráfico:algoritmo para enumerar todos los posibles caminos
Estoy tratando de encontrar una manera de enumerar todos los posibles caminos desde un nodo origen a un nodo de destino. Por ejemplo, de A a E, tenemos las siguientes rutas posibles:
A B C D E
A B C E
A C D E
A C E
Tenga en cuenta que para A C D E, en realidad hay 2 caminos, ya que uno de los caminos utiliza F3 borde y el otro utiliza F5 borde. Además, dado que hay un ciclo entre A y C, puede terminar con un número infinito de rutas, pero a los fines de esto, solo me interesan las rutas en las que no se repite ningún nodo en la ruta de la fuente al objetivo.
Escribí un algoritmo de búsqueda profunda (DFS), pero el problema es que cuando tienes varios bordes entre 2 nodos (como los bordes F3 y F5 anteriores) no estoy seguro de cómo manejarlo. Mi algoritmo solo devuelve las rutas A C D E
y A C E
, no las otras rutas. En el caso de A B C E
, entiendo la razón, porque comienza en A y luego va a C y crea esas rutas, pero cuando el DFS vuelve al nodo B, intenta ir a C, pero C ya ha sido visitado. entonces se detiene
De todos modos, me preguntaba si había una manera de hacer esto, o tal vez esto es NP-completo.
En caso de que quiera ver mi DFS, el código está debajo (disculpe el abuso de macros, los utilizo en la programación del concurso, así que es un hábito).
#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;
}
Salida:
---------- Capture Output ----------
A,C,D,E
A,C,E
Sospecho que este es un problema de topcoder. ¿Cuál es el límite para el tamaño de entrada, en este caso? –
Hola Kit, ¡es un placer encontrarme con usted aquí! No es un problema de TC de una competencia de algo, esta búsqueda se haría en una base de datos. Entonces el tamaño puede ser bastante ilimitado. Estoy pensando que tal vez no hay realmente una solución para esto, ¿qué piensas? – dcp
Encantado de verte también :) Si no hay restricciones en la entrada, entonces tendrás dificultades para sacar todo n! soluciones. Pero si el tamaño del resultado es limitado o es algún tipo de gráfico muy disperso, esto podría funcionar. –