void componentes_fuertes(const Grafo<C> & g, Lista<Lista<int> > & componentes) { // se asume que los vertices fueron numerados de 0 a long-1 bool visitado[g.devolverLongitud()]; for (int i = 0; i < g.devolverLongitud(); i++) visitado[i] = false; Lista<int> vertices; Lista<int> recorrido; g.devolverVertices(vertices); Lista<int>::Iterador it_v = vertices.devolverIterador(); while (!it_v.llegoAlFinal()) { int v = it_v.elementoActual(); if (!visitado[v]) dfs_visit(g, v, visitado, recorrido); it_v.avanzar(); } Grafo<C> g_trasp; traspuesta_grafo(g, g_trasp); for (int i = 0; i < g.devolverLongitud(); i++) visitado[i] = false; it_v = recorrido.devolverIterador(); while (!it_v.llegoAlFinal()) { int v = it_v.elementoActual(); if (!visitado[v]) { Lista<int> componente; dfs_visit(g_trasp, v, visitado, componente); componentes.agregarFinal(componente); } it_v.avanzar(); } }
void mostrar_componentes(Lista<Lista<int> > & componentes, const char impr[]) { Lista<Lista<int> >::Iterador it_comps = componentes.devolverIterador(); while (!it_comps.llegoAlFinal()) { Lista<int> vertices = it_comps.elementoActual(); Lista<int>::Iterador it_v = vertices.devolverIterador(); while (!it_v.llegoAlFinal()) { cout << impr[it_v.elementoActual()] << " "; it_v.avanzar(); } it_comps.avanzar(); cout << endl; } }
void mostrar_caminos(const Grafo<C> & grafo, const Lista<Lista<int> > & caminos, const char impr[]) { Lista<Lista<int> >::ConstIterador it = caminos.devolverIterador(); while (!it.llegoAlFinal()) { mostrar_camino(grafo, it.elementoActual(), impr); it.avanzar(); } }
void mostrar_camino(const Grafo<C> & grafo, const Lista<int> & camino, const char impr[]) { Lista<int>::ConstIterador v = camino.devolverIterador(); while (!v.llegoAlFinal()) { cout << impr[v.elementoActual()] << " "; v.avanzar(); } cout << endl; }
void traspuesta_grafo(const Grafo<C> & g, Grafo<C> & r) { Lista<int> vertices; g.devolverVertices(vertices); Lista<int>::Iterador it_v = vertices.devolverIterador(); while (!it_v.llegoAlFinal()) { r.agregarVertice(it_v.elementoActual()); it_v.avanzar(); } it_v = vertices.devolverIterador(); while (!it_v.llegoAlFinal()) { int v = it_v.elementoActual(); Lista<typename Grafo<C>::Arco> adyacentes; g.devolverAdyacentes(v, adyacentes); typename Lista<typename Grafo<C>::Arco>::Iterador ady = adyacentes.devolverIterador(); while (!ady.llegoAlFinal()) { r.agregarArco(ady.elementoActual().devolverAdyacente(), v, ady.elementoActual().devolverCosto()); ady.avanzar(); } it_v.avanzar(); } }
bool existe_camino_long(const Grafo<C> & g, int origen, int destino, int longi, int longi_actual) { if (longi_actual == longi) return origen == destino; Lista<typename Grafo<C>::Arco> adyacentes; g.devolverAdyacentes(origen, adyacentes); typename Lista<typename Grafo<C>::Arco>::Iterador ady = adyacentes.devolverIterador(); bool existe_camino = false; while (!ady.llegoAlFinal() && !existe_camino) { int v = ady.elementoActual().devolverAdyacente(); existe_camino = existe_camino_long(g, v, destino, longi, longi_actual + 1); ady.avanzar(); } return existe_camino; }
void dfs_visit(const Grafo<C> & g, int v, bool visitado[], Lista<int> & recorrido) { visitado[v] = true; Lista<typename Grafo<C>::Arco> adyacentes; g.devolverAdyacentes(v, adyacentes); typename Lista<typename Grafo<C>::Arco>::Iterador ady = adyacentes.devolverIterador(); while (!ady.llegoAlFinal()) { int w = ady.elementoActual().devolverAdyacente(); if (!visitado[w]) dfs_visit(g, w, visitado, recorrido); ady.avanzar(); } recorrido.agregarPrincipio(v); }
bool ciclo_hamilton(const Grafo<T> & g, int inicio, bool visitado[], int visitados, int v) { if (visitados == g.devolverLongitud()) return true; visitados++; visitado[v] = true; Lista<typename Grafo<T>::Arco> adyacentes; g.devolverAdyacentes(v, adyacentes); typename Lista<typename Grafo<T>::Arco>::Iterador ady = adyacentes.devolverIterador(); bool hay_ciclo = false; while (!hay_ciclo && !ady.llegoAlFinal()) { int u = ady.elementoActual().devolverAdyacente(); if (!poda(visitado, u, inicio, visitados, g.devolverLongitud())) hay_ciclo = ciclo_hamilton(g, inicio, visitado, visitados, u); ady.avanzar(); } visitado[v] = false; return hay_ciclo; }
void caminos_simples(const Grafo<C> & grafo, int origen, int destino, bool visitado[], Lista<Lista<int> > & caminos, Lista<int> & camino_parcial) { visitado[origen] = true; camino_parcial.agregarFinal(origen); if (origen == destino) { caminos.agregarFinal(camino_parcial); camino_parcial.eliminarFinal(); visitado[origen] = false; return; } Lista<typename Grafo<C>::Arco> adyacentes; grafo.devolverAdyacentes(origen, adyacentes); typename Lista<typename Grafo<C>::Arco>::Iterador ady = adyacentes.devolverIterador(); while (!ady.llegoAlFinal()) { int v = ady.elementoActual().devolverAdyacente(); if (!visitado[v]) caminos_simples(grafo, v, destino, visitado, caminos, camino_parcial); ady.avanzar(); } camino_parcial.eliminarFinal(); visitado[origen] = false; }