// Walter Kosters, 21 januari 2008 // Vind aantal elementen van samenhangscomponent van de "puzgraph": // Gegeven een samenhangende graaf met knopen genummerd // 0,1,2,3,...,aantal_knopen-1 // nu mag steeds 0 van plaats wisselen met een aangrenzende knoop // hoeveel samenhangscomponenten levert dit? // Wilson's tricky six puzzle heeft er 6, zie // http://mathworld.wolfram.com/Puz-Graph.html // Invoergraaf: aantal_knopen aantal_takken v11 v12 ... vk1 vk2 // met k = aantal_takken; eerste tak gaat tussen knopen v11 en v12, etc. // Voorbeeld (een driehoek): // 3 3 // 1 2 2 3 3 4 // Compileren: g++ -Wall -o puzgraph puzgraph.cc // Aanroepen: ./puzgraph // #include #include #include #include using namespace std; const int MAX = 20; // maximaal aantal knopen van de graaf class vakje { public: vakje* volgende; int labels[MAX]; int plaats0; };//vakje class Graaf { public: int knopen; int takken; int inhoud[MAX][MAX]; void leesgraaf ( ); void loop ( ); };//Graaf // bereken n! int fac (int n) { int res = 1, i; for ( i = 1; i <= n ; i++ ) res *= i; return res; }//fac // lees graaf in vanuit file void Graaf::leesgraaf ( ) { int een, twee, i, j; string filenaam; ifstream infile; cout << "Filenaam .. "; cin >> filenaam; infile.open (filenaam.c_str ( ),ios::in); for ( i = 0; i < MAX; i++ ) for ( j = 0; j < MAX; j++ ) inhoud[i][j] = false; infile >> knopen >> takken; if ( knopen > MAX ) exit (1); for ( i = 0; i < takken; i++ ) { infile >> een >> twee; inhoud[een-1][twee-1] = inhoud[twee-1][een-1] = true; }//for infile.close ( ); }//Graaf::leesgraaf // het eigenlijke werk void Graaf::loop ( ) { int i, j, teller = 0; bool hetzelfde; vakje* loper; vakje* laatste; vakje* nieuw; vakje* check; vakje* ingang = new vakje; // voor de beginpositie ingang->volgende = NULL; for ( i = 0; i < knopen; i++ ) ingang->labels[i] = i; ingang->plaats0 = 0; laatste = ingang; loper = ingang; while ( loper != NULL ) { for ( i = 0; i < knopen; i++ ) { if ( inhoud[loper->plaats0][i] ) { // i kan verschoven worden nieuw = new vakje; for ( j = 0; j < knopen; j++ ) nieuw->labels[j] = loper->labels[j]; nieuw->volgende = NULL; nieuw->plaats0 = i; nieuw->labels[loper->plaats0] = loper->labels[i]; nieuw->labels[i] = 0; check = ingang; hetzelfde = false; while ( check != NULL && ! hetzelfde ) { // al eerder geweest? hetzelfde = true; for ( j = 0; j < knopen; j++ ) if ( check->labels[j] != nieuw->labels[j] ) hetzelfde = false; check = check->volgende; }//while if ( hetzelfde ) { delete nieuw; nieuw = NULL; }//if else { laatste->volgende = nieuw; laatste = nieuw; }//else }//if }//for loper = loper->volgende; teller++; }//while cout << teller << " element(en)" << endl << fac (knopen) / teller << " samenhangscomponent(en)" << endl; }//Graaf::loop int main ( ) { Graaf G; G.leesgraaf ( ); G.loop ( ); return 0; }//main