I am trying to find all the possible paths from one node in my graph that will visit all other nodes in the graph. I want the function to produce all possibilities of paths in my n*m graph. Each node in my graph has a vector of all neighbors nodes and a Boolean that check if the node is visited or not.
example:
a b
c d
will produce:
abcd
abdc
acbd
...
I tried the solution in this answer, but only return one path. How can I produce all possible paths?
It seems like in some situations by your description you could have infinite paths and a path of infinite length because you didn't specify that nodes couldn't be revisited.
You should implement depth first search and pass a reference to an array of marked (visited) nodes in your recursive DFS method assuming that you have a count of the number of nodes in your graph. After you visit each node, before you leave that node make sure you set it to false again so that it can be reaccessed via another node.
The implementation of this algorithm is really going to depend on how you implemented your graph structure and without the details all I can do is speculate that you have a linked structure with an adjacency list representing the different nodes. I also have no idea how the different nodes map to characters so that is another detail I have to speculate, but say that the nodes are represented by integers.
You need to pass into a DFS method the following: array of marked nodes, a linked list which contains the path information, starting node, (i.e, current node) and final node
void printAllPaths(LinkedList<Integer> currentPath, boolean[] marked, int current, int last){
for( all nodes adjacent to current, node ){
if(node == last){
currentPath.addLast(last);
System.out.println(currentPath);
currentPath.removeLast();
}else if(!marked[node]){
currentPath.addLast(node);
marked[node] = true;
printAllPaths(currentPath, marked, node, final);
marked[node] = false;
currentPath.removeLast();
}
}
}
This will be the basic idea of the code. I apologize if it doesn't compile in advance, but this should print out all of the paths.
Related
This is the first example of the intersection of two linked lists on LeetCode webpage.
The first linked list, A, is [4,1,8,4,5], the second one, B, is [5,6,1,8,4,5]. I found the intersection part of both linked lists is [1,8,4,5]. But the official explanation said "The intersected node's value is 8. From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B."
Can anyone explain that why the started node of the intersection is "8" instead of "1" in this case?
Thanks a lot!
The image provides important context (taken from https://leetcode.com/problems/intersection-of-two-linked-lists/):
You're looking for the point where the two lists start to intersect - this depends on the node connections, not their values. The "1" in both A and B do not imply that they intersect, as the image shows.
i had this same doubt previously, the problem was I was trying to compare the values of nodes, lets say nodeA with a value of 1 and another nodeB with also a value of 1 the problem is if we just compare the nodes in terms of their values we are ignoring the other factors of node like its address, other next elements in node its length, etc. So, instead of matching in terms of nodeA.val == nodeB.val we must be matching in all aspects of a node that is nodeA == nodeB. As shown below:
while node1_to_use is not None and node2_to_use is not None:
if node1_to_use == node2_to_use: # ignore doing this node1_to_use.val == node2_to_use.val
return node2_to_use
node1_to_use = node1_to_use.next
node2_to_use = node2_to_use.next
I saw the following implementation of topological sort using DFS on Leetcode https://leetcode.com/problems/course-schedule/discuss/58509/18-22-lines-C++-BFSDFS-Solutions
Now the part of this that is confusing me is the representation of the directed graph which is used for the top sort. The graph is created as follows:
vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
vector<unordered_set<int>> graph(numCourses);
for (auto pre : prerequisites)
graph[pre.second].insert(pre.first);
return graph;
}
What is confusing me is this line:
graph[pre.second].insert(pre.first);
Presumably the graph is being represented as an adjacency list; if so why is each node being represented by the incoming edges and not the outgoing edges? Interestingly, if I flip pre.second and pre.first like this:
graph[pre.first].insert(pre.second);
The top sort still works. However, it seems most implementations of the same problem use the former method. Does this generalize to all directed graphs? I was taught in my undergraduate degree that a directed graph's adjacency list should contain a list of each nodes outgoing nodes. Is the choice of incoming vs outgoing node arbitrary for the representation of the adjacency list?
To the specific problem which only requires answering true or false, it doesn't matter if you flip every edge. That's because a graph is topological sortable if and only if it has no loops. But if you want an order of taking, it doesn't work as you can see in the different results of [[0, 1]] and [[1, 0]].
Which way to save the graph depends on how you solve the problem. In this given case, we need to know the indegrees of every node (course) and also to update it every time we delete a node from the graph (take the course), so that we know if we can delete a node (we can do it when the indegree is 0). When updating, we minus 1 to each node that the deleted node direct to. If you apply this method (as most do), it's clear how you should save the graph
So, I've implemented a directed graph using an unordered multimap. Each pair within the map is made up of two strings: the vertex and its adjacent vertex.
Now, I am trying to determine if my graph has a cycle, and if so, how big is the cycle. This is the code I have so far:
int findCycle(const unordered_multimap<string,string> & connectedURLVertices, string y, string key)
{
string position;
position=y.find(key);
if(position!=string::npos)
{
return 1;
}
auto nodesToCheck=connectedURLVertices.equal_range(key);
for(auto & node : nodesToCheck)
{
int z=findCycle(connectedURLVertices,y+key,node);
}
}
I've walked through the code on paper and it seems to be logically correct, but I would appreciate it if anyone could take a look and see if I am on the right track or missing anything. Thanks!
To search for cycles in a graph you have to descend recursively through the arcs from some initial node until you reach one already visited node (you can construct a std::set of already visited nodes or mark the nodes as you visit them) or exhaust all the nodes without getting one already visited (absence of cycles) The criterion to select the arc can be adjusted to find it more quickly or the kind of search (first in depth, search by level, etc.)
Given a tree(By tree , I mean N Nodes , N-1 edges and it is connected) the root of tree is changed to lets say r. Now given another node lets say t , you have to find the sum of all nodes in the subtree rooted at t.
I was trying to implement it in c++ .
std::map<int, std::vector< pair<int,int> > > map;
if I iterate over the vector map[t] , I have to ensure that it does not go to a path which leads to r . How would I ensure that ?
Also is there a better way to store a tree in c++ , given the conditions that the root of the tree might change ? I think there will be because the map does not convey anything about a root . :)
The problem is that you have your tree stored as a general graph. Hence for a given vertex you don't know which is the arc leading towards the root (i.e. the parent).
The solution very much depends on the context. A simple solution would be a depth first search starting from r and looking for t. As soon as you find t you have found also the parent of t, and you can easily identify the subtree starting from t.
Alternatively you can start from t and look for r. When you find r you have found the parent of t and you can traverse all other arcs to find the subtree of t.
About an alternative representation of the graph, usually it is better to keep a list of vertices and for each vertex keep a list of neighbour vertices as in:
std::map<int, std::list<int> >
Iam new to c++.I have to write a c++ program representing a graph where the node has many edges as input and single edge as its output.I should also label them.I felt using linked list would help me but i was struck by the thought that in a linked list i would only have a single edge to a given node and another edge going to the next node.Is there any possible way of representing many different edges from different nodes to a single node.
So a node should look something like this:
struct Node
{
Node(std::string label_) : label(label_) {}
std::string label;
std::vector<Node*> incoming;
Node* outgoing = nullptr;
}
Then it's just a matter of wiring them together. Note this is sort of like a linked list of strings, except that the "previous" pointer (incoming) is multiple instead of singular.
From here, note that what you are actually building is a tree (assuming one node has a null outgoing pointer). That may help you to find an existing data structure implementation that you can use instead of building your own.