I recently encountered this problem (Edit: Problem A) from the Spotify hacker problem earlier this year, which includes the definition of a train switch to transfer the train back to it. The train should arrive in the same direction in which it remained, and the train will never be able to return to the tracks.
As I understand it, the problem can be modeled as an undirected (?) Graph, where we must find the shortest cycle from a certain vertex or find that such a cycle does not exist. However, the interesting part is that for a vertex v, the vertices adjacent to v depend on the path taken in v, therefore, in a sense, the graph can be considered directional, although this direction depends on the path.
My first thought was to simulate each node as 3 separate vertices, A, B and C, where A β B and A β C, and then use the width search to create a search until we find the original vertex, but this complicated by the warning described above, namely, that the adjacencies for a given vertex depend on the previous vertex that we visited. This means that in our BFS tree, nodes can have multiple parents.
Obviously, a simple BFS search is not enough to solve this problem. I know that there are algorithms that exist to detect loops in a graph. One approach may be to detect all cycles, and then determine for each cycle whether the path is valid. (i.e. does not reverse direction)
Does anyone else have any ideas on approaches to solve this problem?
UPDATE: I followed the approach suggested by @Karussell in the comments.
Here is my solution for github.
The trick was to model the situation using a graph graph rather than a traditional vertex graph. The input file provided in the competition is convenient to specify in terms of edges, so this file can be easily used to build a boundary graph.
The program uses two important classes: Road and Solver. The road has two integer fields: j1 and j2. j1 is the source compound, and j2 is the target compound. Each road is one-way, which means that you can only move from j1 to j2. Each road also includes a LinkedList of neighboring roads and a parent road. The Road class also includes static methods for converting between lines used in the input file and integer indices representing points A, B, and C on each node.
For each entry in the input file, we add two roads to the HashMap, one road for each direction between two intersections. Now we have a list of all the roads that pass between crossings. We just need to connect the roads together at the junctions through switches A, B and C. If the road ends at Junction.A, we look at the roads that start at Junction.B and Junction.C and add these roads as an adjunction. The buildGraph () function returns a path whose target connection (j2) is "1A" == index 0.
At this moment, our schedule is built. To find the shortest path, I just used BFS to move the chart. We leave the root unmarked and start with lines of root adjoins. If we find a road whose target connection is β1Aβ (index 0), then we find the shortest cycle through the starting point. As soon as we reconstruct the path using each parent property of Road, the trivial task must be appropriately defined in this problem.
Thanks to Karussell for suggesting this approach. If you want to put your comment in the response form with a brief explanation, I agree with her. Thanks @Origin, as well. I must admit that I did not fully follow the logic of your answer, but this, of course, does not mean that this is not true. If someone solves this problem using your solution, I would be very interested to see it.