// Wyszukiwanie cykli i ścieżek Hamiltona
// Data: 10.02.2014
// (C)2014 mgr Jerzy Wałaszek
//---------------------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// Typy danych
struct SLel
{
SLel * next;
int v;
};
// Zmienne globalne
int m, n; // Liczba krawędzi i wierzchołków
SLel **graf; // Tablica list sąsiedztwa
int *S; // Tablica-stos
int sptr; // Wskaźnik stosu
bool *visited; // Tablica odwiedzin
// Rekurencyjna procedura wyznaczająca ścieżki i cykle Hamiltona
// v-wierzchołek bieżący
//--------------------------------------------------------------
void DFSHamilton (int v)
{
int i;
bool test;
SLel *p;
S [sptr++] = v; // Wierzchołek v na stos
if(sptr < n) // Jest ścieżka Hamiltona?
{
visited [v] = true; // Nie ma, odwiedzamy v
for(p = graf [v]; p; p = p->next) // Przeglądamy sąsiadów v
if(!visited [p->v]) DFSHamilton (p->v); // Wywołanie rekurencyjne
visited [v] = false; // Wycofujemy się z v
}
else // Jest ścieżka Hamiltona
{
test = false; // Zakładamy brak cyklu
for(p = graf [v]; p; p = p->next) // Przeglądamy sąsiadów
if(! (p->v)) // Jeśli sąsiadem jest wierzchołek 0,
{
test = true; // to mamy cykl
break;
}
if(test) cout << "Hamiltonian Cycle :";
else cout << "Hamiltonian Path :";
for(i = 0; i < sptr; i++) // Wypisujemy ścieżkę Hamiltona
cout << setw (3) << S [i];
if(test) cout << setw (3) << 0; // Dla cyklu dopisujemy wierzchołek startowy
cout << endl;
}
sptr--; // Wierzchołek v usuwamy ze stosu
}
// **********************
// *** PROGRAM GŁÓWNY ***
// **********************
int main()
{
int i, v1, v2;
SLel *p, *r;
cin >> n >> m; // Czytamy liczbę wierzchołków i krawędzi
// Tworzymy tablice dynamiczne
graf = new SLel * [n];
visited = new bool [n];
for(i = 0; i < n; i++)
{
graf [i] = NULL;
visited [i] = false;
}
S = new int [n];
sptr = 0;
// Odczytujemy definicje krawędzi grafu
for(i = 0; i < m; i++)
{
cin >> v1 >> v2;
p = new SLel;
p->v = v2;
p->next = graf [v1];
graf [v1] = p;
}
cout << endl;
// Wyświetlamy ścieżki i cykle Hamiltona
DFSHamilton (0);
// Usuwamy zmienne dynamiczne
delete [] visited;
delete [] S;
for(i = 0; i < n; i++)
{
p = graf [i];
while(p)
{
r = p;
p = p->next;
delete r;
}
}
delete [] graf;
return 0;}