{"id":27541,"date":"2018-02-06T20:56:49","date_gmt":"2018-02-06T15:26:49","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=27541"},"modified":"2018-02-06T20:56:49","modified_gmt":"2018-02-06T15:26:49","slug":"union-find-algorithm-set-1-detect-cycle-undirected-graph-3","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/union-find-algorithm-set-1-detect-cycle-undirected-graph-3\/","title":{"rendered":"Union-Find Algorithm | Set 1 (Detect Cycle in an Undirected Graph)"},"content":{"rendered":"<p>A <em><a href=\"http:\/\/en.wikipedia.org\/wiki\/Disjoint-set_data_structure\" target=\"_blank\" rel=\"noopener\">disjoint-set data structure<\/a><\/em> is a data structure that keeps track of a set of elements partitioned into a number of disjoint (non-overlapping) subsets.<span id=\"more-26350\"><\/span> A <a href=\"http:\/\/en.wikipedia.org\/wiki\/Disjoint-set_data_structure\" target=\"_blank\" rel=\"noopener\"><em>union-find algorithm<\/em><\/a> is an algorithm that performs two useful operations on such a data structure:<\/p>\n<p><em><strong>Find:<\/strong><\/em> Determine which subset a particular element is in. This can be used for determining if two elements are in the same subset.<\/p>\n<p><em><strong>Union:<\/strong><\/em> Join two subsets into a single subset.<\/p>\n<p>In this post, we will discuss an application of Disjoint Set Data Structure. The application is to check whether a given graph contains a cycle or not.<\/p>\n<p><em>Union-Find Algorithm<\/em> can be used to check whether an undirected graph contains cycle or not. Note that we have discussed an <a href=\"http:\/\/www.geeksforgeeks.org\/archives\/18516\" target=\"_blank\" rel=\"noopener\">algorithm to detect cycle<\/a>. This is another method based on <em>Union-Find<\/em>. This method assumes that graph doesn\u2019t contain any self-loops.<br \/>\nWe can keeps track of the subsets in a 1D array, lets call it parent[].<\/p>\n<p>Let us consider the following graph:<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-27549\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Cycle-in-graph.png\" alt=\"Union-Find Algorithm | Set 1 (Detect Cycle in an Undirected Graph)\" width=\"262\" height=\"195\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Cycle-in-graph.png 262w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Cycle-in-graph-74x55.png 74w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Cycle-in-graph-111x83.png 111w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Cycle-in-graph-215x161.png 215w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/06\/Cycle-in-graph-260x195.png 260w\" sizes=\"(max-width: 262px) 100vw, 262px\" \/><\/p>\n<p>For each edge, make subsets using both the vertices of the edge. If both the vertices are in the same subset, a cycle is found.<\/p>\n<p>Initially, all slots of parent array are initialized to -1 (means there is only one item in every subset).<\/p>\n<pre>0   1   2\r\n-1 -1  -1<\/pre>\n<p>Now process all edges one by one.<\/p>\n<p><em>Edge 0-1:<\/em> Find the subsets in which vertices 0 and 1 are. Since they are in different subsets, we take the union of them. For taking the union, either make node 0 as parent of node 1 or vice-versa.<\/p>\n<pre>0   1   2    &lt;----- 1 is made parent of 0 (1 is now representative of subset {0, 1})\r\n1  -1  -1<\/pre>\n<p><em>Edge 1-2:<\/em> 1 is in subset 1 and 2 is in subset 2. So, take union.<\/p>\n<pre>0   1   2    &lt;----- 2 is made parent of 1 (2 is now representative of subset {0, 1, 2})\r\n1   2  -1<\/pre>\n<p><em>Edge 0-2:<\/em> 0 is in subset 2 and 2 is also in subset 2. Hence, including this edge forms a cycle.<\/p>\n<p>How subset of 0 is same as 2?<br \/>\n0-&gt;1-&gt;2 \/\/ 1 is parent of 0 and 2 is parent of 1<\/p>\n<p>Based on the above explanation, below are implementations:<\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <\/div> <pre class=\"language-c code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-c code-embed-code\">\/\/ A union-find algorithm to detect cycle in a graph<br\/>#include &lt;stdio.h&gt;<br\/>#include &lt;stdlib.h&gt;<br\/>#include &lt;string.h&gt;<br\/> <br\/>\/\/ a structure to represent an edge in graph<br\/>struct Edge<br\/>{<br\/>    int src, dest;<br\/>};<br\/> <br\/>\/\/ a structure to represent a graph<br\/>struct Graph<br\/>{<br\/>    \/\/ V-&gt; Number of vertices, E-&gt; Number of edges<br\/>    int V, E;<br\/> <br\/>    \/\/ graph is represented as an array of edges<br\/>    struct Edge* edge;<br\/>};<br\/> <br\/>\/\/ Creates a graph with V vertices and E edges<br\/>struct Graph* createGraph(int V, int E)<br\/>{<br\/>    struct Graph* graph = <br\/>           (struct Graph*) malloc( sizeof(struct Graph) );<br\/>    graph-&gt;V = V;<br\/>    graph-&gt;E = E;<br\/> <br\/>    graph-&gt;edge = <br\/>        (struct Edge*) malloc( graph-&gt;E * sizeof( struct Edge ) );<br\/> <br\/>    return graph;<br\/>}<br\/> <br\/>\/\/ A utility function to find the subset of an element i<br\/>int find(int parent[], int i)<br\/>{<br\/>    if (parent[i] == -1)<br\/>        return i;<br\/>    return find(parent, parent[i]);<br\/>}<br\/> <br\/>\/\/ A utility function to do union of two subsets <br\/>void Union(int parent[], int x, int y)<br\/>{<br\/>    int xset = find(parent, x);<br\/>    int yset = find(parent, y);<br\/>    parent[xset] = yset;<br\/>}<br\/> <br\/>\/\/ The main function to check whether a given graph contains <br\/>\/\/ cycle or not<br\/>int isCycle( struct Graph* graph )<br\/>{<br\/>    \/\/ Allocate memory for creating V subsets<br\/>    int *parent = (int*) malloc( graph-&gt;V * sizeof(int) );<br\/> <br\/>    \/\/ Initialize all subsets as single element sets<br\/>    memset(parent, -1, sizeof(int) * graph-&gt;V);<br\/> <br\/>    \/\/ Iterate through all edges of graph, find subset of both<br\/>    \/\/ vertices of every edge, if both subsets are same, then <br\/>    \/\/ there is cycle in graph.<br\/>    for(int i = 0; i &lt; graph-&gt;E; ++i)<br\/>    {<br\/>        int x = find(parent, graph-&gt;edge[i].src);<br\/>        int y = find(parent, graph-&gt;edge[i].dest);<br\/> <br\/>        if (x == y)<br\/>            return 1;<br\/> <br\/>        Union(parent, x, y);<br\/>    }<br\/>    return 0;<br\/>}<br\/> <br\/>\/\/ Driver program to test above functions<br\/>int main()<br\/>{<br\/>    \/* Let us create following graph<br\/>         0<br\/>        |  \\<br\/>        |    \\<br\/>        1-----2 *\/    <br\/>    int V = 3, E = 3;<br\/>    struct Graph* graph = createGraph(V, E);<br\/> <br\/>    \/\/ add edge 0-1<br\/>    graph-&gt;edge[0].src = 0;<br\/>    graph-&gt;edge[0].dest = 1;<br\/> <br\/>    \/\/ add edge 1-2<br\/>    graph-&gt;edge[1].src = 1;<br\/>    graph-&gt;edge[1].dest = 2;<br\/> <br\/>    \/\/ add edge 0-2<br\/>    graph-&gt;edge[2].src = 0;<br\/>    graph-&gt;edge[2].dest = 2;<br\/> <br\/>    if (isCycle(graph))<br\/>        printf( &quot;graph contains cycle&quot; );<br\/>    else<br\/>        printf( &quot;graph doesn&#039;t contain cycle&quot; );<br\/> <br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<p>Output:<\/p>\n<pre>graph contains cycle<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Union-Find Algorithm | Set 1 (Detect Cycle in an Undirected Graph)-Graph cycle-A disjoint-set data structure is a data structure that keeps track of a set.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[81350,81352],"tags":[76546,76378,81747,76366,76368,76365,76367,76364],"class_list":["post-27541","post","type-post","status-publish","format-standard","hentry","category-graph","category-graph-cycle","tag-detect-cycle-in-directed-graph","tag-disjoint-set-data-structure-c","tag-disjoint-set-data-structure-example","tag-union-find-algorithm-c","tag-union-find-algorithm-java","tag-union-find-geeksforgeeks","tag-union-find-path-compression","tag-union-find-wiki"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/27541","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=27541"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/27541\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=27541"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=27541"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=27541"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}