1

So, I have an assignment to do in C++, but I can't figure out how to :/
I have to use backtracking, which is completely alien to me.

The problem: You are given n number of people with their names and m number of relations(friends) between them. Each relation consists of two names, forming a pair of strings. Everyone has at least n/2 friends. The first person has a book which he lends to one of his friends.
The book has to "travel" through everyone and end up in the hands of the first person.
Write out every possible solution.
The input should contain a number for n followed by a number for m followed by m number of rows each containing a relation.

Something like this:

The input...

3 3
Matt Susy
Matt Alan
Susy Alan

...would result in:

Matt Susy Alan Matt
Matt Alan Susy Matt

and so on for more people.

I have been banging my head against the table because no matter what I do, I can't figure it out :/
As I said, this is a relatively new concept for me and every little help would be appreciated :)

The thing is that this code works, but I can't submit it, because the teacher said that someone already approached this problem using this method, so I have to come up with a different solution for it. (Believe it or not, this has happened too many times already...)
The base idea can have some resemblance to this one, but a different approach would be better.
Please forgive the names of the variables, english is not my first language so I wrote it using words from my language :)

#include<iostream>
#include<fstream>

using namespace std;

void input_1D(string nev_1D[])
{
     ifstream be("skam0286_L6_9.txt");
     int x, i, j, k=1, ok;
     string akt;
     be>>x>>x;
     for(i=0; i<2*x; ++i)
     {
          be>>akt;
          for(j=1, ok=1; j<=k; ++j)  if(nev_1D[j]==akt) ok=0;
          if(ok) nev_1D[k++]=akt;
     }
     be.close();
}

void input_2D(int &n, int &m, string nev_2D[][3])
{
  int i;
  ifstream be("skam0286_L6_9.txt");
  be>>n>>m;
  for(i=1;i<=m;++i)  be>>nev_2D[i][1]>>nev_2D[i][2];
    be.close();
}

void output(int n, string eredm[])
{
  int i;
  for(i=1;i<=n;i++) cout<<eredm[i]<<" ";
  cout<<endl;
}

bool helyes(int n, string akt, string eredm[])
{
  int i, ok=0;
  for(i=1; i<n && !ok; ++i)
    if(eredm[i]==akt) ok=1;
  return ok;
}

bool barat(int m, string nev_2D[][3], string n1, string n2)
{
  int i, ok=0;
  for(i=1;i<=m && !ok; ++i)
    if((n1==nev_2D[i][1] && n2==nev_2D[i][2])||(n1==nev_2D[i][2] && n2==nev_2D[i][1]))
       ok=1;
  return ok;
}

void bt(int n, int m, string nev_2D[][3], string nev_1D[], string eredm[], int ind)
{
  if(ind==n+1){
    if(barat(m, nev_2D, eredm[1], eredm[ind-1])){
      eredm[ind]=eredm[1];
      output(ind, eredm);
    }
  }
  else{
    int i;
    for(i=1; i<=n; ++i)
      if(!helyes(ind, nev_1D[i], eredm) && barat(m, nev_2D, eredm[ind-1], nev_1D[i])){
        eredm[ind]=nev_1D[i];
        bt(n, m, nev_2D, nev_1D, eredm, ind+1);
      }
  }
}

int main()
{
  int n, m;
  string nev_2D[100][3], nev_1D[100], eredm[100];
  eredm[1]="Matt";
  input_2D(n,m,nev_2D);
  input_1D(nev_1D);
  bt(n, m, nev_2D, nev_1D, eredm, 2);
  return 0;
}
Moenish
  • 35
  • 5
  • 1
    What have you tried? What does your current attempt look like in [mcve] form? – Jesper Juhl Feb 12 '20 at 19:29
  • 2
    This is a graph problem. Nodes are the persons. Edges are friendships. You are looking for all [Hamiltonian Cycles](https://en.wikipedia.org/wiki/Hamiltonian_path). – amit Feb 12 '20 at 19:31
  • 1
    By the way, this has nothing to do specifically with C++. I'd edit the tags removing C++ and adding recursive-backtracking, algorithm and graph, for instance. It may help you obtain a general algorithmic answer which you'd more easily converto to C++. – Tarc Feb 12 '20 at 19:31
  • 1
    I took the liberty to change the tags you assigned. – Tarc Feb 12 '20 at 19:35
  • @Tarc Thanks a lot, did not know what to write there specifically :) – Moenish Feb 12 '20 at 19:38
  • @JesperJuhl well I'm a bit embarassed by it, but the only thing that somewhat worked was to loop through every single person and the resulting chain multiple times to check if the name was already used up and inserting it if it wasn't. But I scratched this idea thinking it was way too resource-heavy. – Moenish Feb 12 '20 at 19:41
  • @amit Allright, I'll look into it, thanks :) – Moenish Feb 12 '20 at 19:42
  • @Moenish If that's your best current attempt, then show that. A "stupid" attempt at least shows you *tried* and gives us some code to bite into/comment on. That's a *lot* better than a question without code. – Jesper Juhl Feb 12 '20 at 19:47
  • @JesperJuhl Not sure if it is the best way, but I uploaded it as an answer. It basically inserts the names into a nx2 matrix where each row contains a different relation. Then using that it constructs an array where each name only appears once. Then permutates the array to form the chains. – Moenish Feb 12 '20 at 20:17
  • @Moenish Ehh, why post it as an answer (it is not one)? Why not just edit your question and include it there? – Jesper Juhl Feb 12 '20 at 20:18
  • @JesperJuhl That's... a great idea :D will do. – Moenish Feb 12 '20 at 20:20
  • @JesperJuhl I can't find it as in the file does not exist anymore because I "professionally" cleaned out old files from my PC and accidentally deleted my homework folder with them because I wasn't careful enough. I tried restoring it, but it must have already been overwritten by something, because the restored file is corrupted. I will migrate every code I wrote to github once I have time for it. – Moenish Feb 12 '20 at 20:26

0 Answers0