{"id":110,"date":"2009-10-02T23:32:32","date_gmt":"2009-10-02T22:32:32","guid":{"rendered":"http:\/\/klondike.xiscosoft.es\/klog\/?p=110"},"modified":"2009-10-02T23:34:07","modified_gmt":"2009-10-02T22:34:07","slug":"an-easy-to-understand-but-efficient-algorithm-to-know-the-nodes-which-a-in-any-path-from-a-to-b","status":"publish","type":"post","link":"https:\/\/klondike.es\/klog\/2009\/10\/02\/an-easy-to-understand-but-efficient-algorithm-to-know-the-nodes-which-a-in-any-path-from-a-to-b\/","title":{"rendered":"An easy to understand (but efficient) algorithm to know the nodes which are in any path from a to b"},"content":{"rendered":"<p>Today I had to face a simple but interesting graph problem: Given a graph and two nodes a and b. Find all the nodes which form part of any of the possible paths from a to b.<\/p>\n<p>Though it may seem a bit difficult for starters it can be solved easily using a simple algorithm and knowing a few things:<\/p>\n<p><!--more-->First we take the graph G and find the reverse graph G&#8217; (this is a Graph with the edges reversed).<\/p>\n<p>This would be the transposition of the connection matrix or could be done easily if the graph is represented as a vector of lists of nodes with a edge from its position going over each position on the vector and adding that position to the list on G&#8217; on the position of every node in that list.<\/p>\n<p>Now we will take a list L of all the nodes on G which are reachable from A. This can be easily done:<\/p>\n<p>Q := queue<br \/>\nV :- bool vector size nodes(G) initialized to false<br \/>\nV[A] = True<br \/>\nQ.insert A<br \/>\nWhile ! Q.empty<\/p>\n<p style=\"padding-left: 30px;\">n = Q.top<br \/>\nQ.pop<br \/>\nForeach Q.edgeFrom(n) e #This is for each node with an edge from n to it\n<\/p>\n<p style=\"padding-left: 60px;\">If (!V[e])<\/p>\n<p style=\"padding-left: 90px;\">Q.insert n<br \/>\nV[e] = True<\/p>\n<p>Then V will be True for each node reachable from A<\/p>\n<p>We do the same with G&#8217; and B and store it on L&#8217;<\/p>\n<p>Finally if a node is in both L and L&#8217; then it is part of at least one path from A to B<\/p>\n<p>Now the explanation on why it works:<\/p>\n<ul>\n<li>If n is connected in G to A then there is at least one path P1 from A to n<\/li>\n<li>If n is connected in G&#8217; to B then there is at least one path P2 from B to n<\/li>\n<li>As G&#8217; is G with its edges reversed then the reverse of P2, P2&#8221; will be the path from n to B on G<\/li>\n<li>As there is a path from A to n and another from n to B then n is part of the path P1,n,P2&#8242; which is a path from A to B so n is in at least one path from A to B<\/li>\n<\/ul>\n<p>Finally to Big O calculation of its costs:<\/p>\n<p>The cost of finding G&#8217; is either O(N\u00b2) (If the graph is represented as a matrix whereh M[i,j] is 1 if there is a edge from i to j) or O(N+E) (If the graph is presented as a vector of lists of nodes reachable from i)<\/p>\n<p>The cost of reachability is either O(N\u00b2) in the first case or O(N+E) on the second.<\/p>\n<p>So the cost of this algorithm is either O(N\u00b2) or O(N+E) depending on the representation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today I had to face a simple but interesting graph problem: Given a graph and two nodes a and b. Find all the nodes which form part of any of the possible paths from a to b. Though it may seem a bit difficult for starters it can be solved easily using a simple algorithm [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-110","post","type-post","status-publish","format-standard","hentry","category-otras-cosas"],"_links":{"self":[{"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/posts\/110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/comments?post=110"}],"version-history":[{"count":3,"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/posts\/110\/revisions"}],"predecessor-version":[{"id":112,"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/posts\/110\/revisions\/112"}],"wp:attachment":[{"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/media?parent=110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/categories?post=110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/klondike.es\/klog\/wp-json\/wp\/v2\/tags?post=110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}