<ahref="connected__components_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aname="l00001"></a><spanclass="lineno"> 1</span> <spanclass="comment">// Copyright 2010-2018 Google LLC</span></div>
<divclass="line"><aname="l00002"></a><spanclass="lineno"> 2</span> <spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aname="l00003"></a><spanclass="lineno"> 3</span> <spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aname="l00004"></a><spanclass="lineno"> 4</span> <spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aname="l00008"></a><spanclass="lineno"> 8</span> <spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aname="l00009"></a><spanclass="lineno"> 9</span> <spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aname="l00010"></a><spanclass="lineno"> 10</span> <spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aname="l00011"></a><spanclass="lineno"> 11</span> <spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aname="l00012"></a><spanclass="lineno"> 12</span> <spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aname="l00015"></a><spanclass="lineno"> 15</span> <spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aname="l00016"></a><spanclass="lineno"> 16</span> <spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aname="l00017"></a><spanclass="lineno"> 17</span> <spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aname="l00021"></a><spanclass="lineno"> 21</span> <spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aname="l00022"></a><spanclass="lineno"> 22</span> <spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aname="l00023"></a><spanclass="lineno"> 23</span> <spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aname="l00024"></a><spanclass="lineno"> 24</span> <spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aname="l00025"></a><spanclass="lineno"> 25</span> <spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aname="l00027"></a><spanclass="lineno"> 27</span> <spanclass="comment">// Finds the connected components in an undirected graph:</span></div>
<divclass="line"><aname="l00030"></a><spanclass="lineno"> 30</span> <spanclass="comment">// If you have a fixed graph where the node are dense integers, use</span></div>
<divclass="line"><aname="l00031"></a><spanclass="lineno"> 31</span> <spanclass="comment">// GetConnectedComponents(): it's very fast and uses little memory.</span></div>
<divclass="line"><aname="l00033"></a><spanclass="lineno"> 33</span> <spanclass="comment">// If you have a more dynamic scenario where you want to incrementally</span></div>
<divclass="line"><aname="l00034"></a><spanclass="lineno"> 34</span> <spanclass="comment">// add nodes or edges and query the connectivity between them, use the</span></div>
<divclass="line"><aname="l00035"></a><spanclass="lineno"> 35</span> <spanclass="comment">// [Dense]ConnectedComponentsFinder class, which uses the union-find algorithm</span></div>
<divclass="line"><aname="l00057"></a><spanclass="lineno"> 57</span> <spanclass="comment">// Finds the connected components of the graph, using BFS internally.</span></div>
<divclass="line"><aname="l00058"></a><spanclass="lineno"> 58</span> <spanclass="comment">// Works on any *undirected* graph class whose nodes are dense integers and that</span></div>
<divclass="line"><aname="l00059"></a><spanclass="lineno"> 59</span> <spanclass="comment">// supports the [] operator for adjacency lists: graph[x] must be an integer</span></div>
<divclass="line"><aname="l00060"></a><spanclass="lineno"> 60</span> <spanclass="comment">// container listing the nodes that are adjacent to node #x.</span></div>
<divclass="line"><aname="l00063"></a><spanclass="lineno"> 63</span> <spanclass="comment">// "Undirected" means that for all y in graph[x], x is in graph[y].</span></div>
<divclass="line"><aname="l00065"></a><spanclass="lineno"> 65</span> <spanclass="comment">// Returns the mapping from node to component index. The component indices are</span></div>
<divclass="line"><aname="l00066"></a><spanclass="lineno"> 66</span> <spanclass="comment">// deterministic: Component #0 will be the one that has node #0, component #1</span></div>
<divclass="line"><aname="l00067"></a><spanclass="lineno"> 67</span> <spanclass="comment">// the one that has the lowest-index node that isn't in component #0, and so on.</span></div>
<divclass="line"><aname="l00069"></a><spanclass="lineno"> 69</span> <spanclass="comment">// Example on the following 6-node graph: 5--3--0--1 2--4</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// NOTE(user): The rest of the functions below should also be in namespace</span></div>
<divclass="line"><aname="l00078"></a><spanclass="lineno"> 78</span> <spanclass="comment">// util, but for historical reasons it hasn't been done yet.</span></div>
<divclass="line"><aname="l00080"></a><spanclass="lineno"> 80</span> <spanclass="comment">// A connected components finder that only works on dense ints.</span></div>
<divclass="line"><aname="l00090"></a><spanclass="lineno"> 90</span> <spanclass="comment">// The main API is the same as ConnectedComponentsFinder (below): see the</span></div>
<divclass="line"><aname="l00098"></a><spanclass="lineno"> 98</span> <spanclass="comment">// Gets the current set of root nodes in sorted order. Runs in amortized</span></div>
<divclass="line"><aname="l00102"></a><spanclass="lineno"> 102</span> <spanclass="comment">// Sets the number of nodes in the graph. The graph can only grow: this</span></div>
<divclass="line"><aname="l00103"></a><spanclass="lineno"> 103</span> <spanclass="comment">// dies if "num_nodes" is lower or equal to any of the values ever given</span></div>
<divclass="line"><aname="l00104"></a><spanclass="lineno"> 104</span> <spanclass="comment">// to AddEdge(), or lower than a previous value given to SetNumberOfNodes().</span></div>
<divclass="line"><aname="l00105"></a><spanclass="lineno"> 105</span> <spanclass="comment">// You need this if there are nodes that don't have any edges.</span></div>
<divclass="line"><aname="l00108"></a><spanclass="lineno"> 108</span> <spanclass="comment">// Returns the root of the set for the given node. node must be in</span></div>
<divclass="line"><aname="l00110"></a><spanclass="lineno"> 110</span> <spanclass="comment">// Non-const because it does path compression internally.</span></div>
<divclass="line"><aname="l00113"></a><spanclass="lineno"> 113</span> <spanclass="comment">// Returns the same as GetConnectedComponents().</span></div>
<divclass="line"><aname="l00117"></a><spanclass="lineno"> 117</span> <spanclass="comment">// parent[i] is the id of an ancestor for node i. A node is a root iff</span></div>
<divclass="line"><aname="l00120"></a><spanclass="lineno"> 120</span> <spanclass="comment">// If i is a root, component_size_[i] is the number of elements in the</span></div>
<divclass="line"><aname="l00121"></a><spanclass="lineno"> 121</span> <spanclass="comment">// component. If i is not a root, component_size_[i] is meaningless.</span></div>
<divclass="line"><aname="l00127"></a><spanclass="lineno"> 127</span> <spanclass="comment">// The current roots. This is maintained lazily by GetComponentRoots().</span></div>
<divclass="line"><aname="l00129"></a><spanclass="lineno"> 129</span> <spanclass="comment">// The number of nodes that existed the last time GetComponentRoots() was</span></div>
<divclass="line"><aname="l00135"></a><spanclass="lineno"> 135</span> <spanclass="comment">// A helper to deduce the type of map to use depending on whether CompareOrHashT</span></div>
<divclass="line"><aname="l00136"></a><spanclass="lineno"> 136</span> <spanclass="comment">// is a comparator or a hasher (prefer the latter).</span></div>
<divclass="line"><aname="l00139"></a><spanclass="lineno"> 139</span> <spanclass="comment">// SFINAE trait to detect hash functors and select unordered containers if so,</span></div>
<divclass="line"><aname="l00140"></a><spanclass="lineno"> 140</span> <spanclass="comment">// and ordered containers otherwise (= by default).</span></div>
<divclass="line"><aname="l00141"></a><spanclass="lineno"> 141</span> <spanclass="keyword">template</span><<spanclass="keyword">typename</span> U, <spanclass="keyword">typename</span> E = <spanclass="keywordtype">void</span>></div>
<divclass="line"><aname="l00147"></a><spanclass="lineno"> 147</span> <spanclass="comment">// The expression inside decltype is basically saying that "H(x)" is</span></div>
<divclass="line"><aname="l00148"></a><spanclass="lineno"> 148</span> <spanclass="comment">// well-formed, where H is an instance of U and x is an instance of T, and is</span></div>
<divclass="line"><aname="l00149"></a><spanclass="lineno"> 149</span> <spanclass="comment">// a value of integral type. That is, we are "duck-typing" on whether U looks</span></div>
<divclass="line"><aname="l00150"></a><spanclass="lineno"> 150</span> <spanclass="comment">// like a hash functor.</span></div>
<divclass="line"><aname="l00153"></a><spanclass="lineno"> 153</span>  U, <aclass="code"href="namespaceabsl.html">absl</a>::enable_if_t<std::is_integral<decltype(std::declval<const U&>()(</div>
<divclass="line"><aname="l00170"></a><spanclass="lineno"> 170</span> <spanclass="comment">// ... repeating, adding nodes and edges as needed. Adding an edge</span></div>
<divclass="line"><aname="l00171"></a><spanclass="lineno"> 171</span> <spanclass="comment">// will automatically also add the two nodes at its ends, if they</span></div>
<divclass="line"><aname="l00172"></a><spanclass="lineno"> 172</span> <spanclass="comment">// haven't already been added.</span></div>
<divclass="line"><aname="l00175"></a><spanclass="lineno"> 175</span> <spanclass="comment">// Each entry in components now contains all the nodes in a single</span></div>
<divclass="line"><aname="l00187"></a><spanclass="lineno"> 187</span> <spanclass="comment">// If you want to, you can continue adding nodes and edges after calling</span></div>
<divclass="line"><aname="l00188"></a><spanclass="lineno"> 188</span> <spanclass="comment">// FindConnectedComponents, then call it again later.</span></div>
<divclass="line"><aname="l00190"></a><spanclass="lineno"> 190</span> <spanclass="comment">// If your node type isn't STL-friendly, then you can use pointers to</span></div>
<divclass="line"><aname="l00191"></a><spanclass="lineno"> 191</span> <spanclass="comment">// it instead:</span></div>
<divclass="line"><aname="l00194"></a><spanclass="lineno"> 194</span> <spanclass="comment">// ... and so on...</span></div>
<divclass="line"><aname="l00195"></a><spanclass="lineno"> 195</span> <spanclass="comment">// Of course, in this usage, the connected components finder retains</span></div>
<divclass="line"><aname="l00196"></a><spanclass="lineno"> 196</span> <spanclass="comment">// these pointers through its lifetime (though it doesn't dereference them).</span></div>
<divclass="line"><aname="l00207"></a><spanclass="lineno"> 207</span> <spanclass="comment">// Adds a node in the graph. It is OK to add the same node more than</span></div>
<divclass="line"><aname="l00208"></a><spanclass="lineno"> 208</span> <spanclass="comment">// once; additions after the first have no effect.</span></div>
<divclass="line"><aname="l00211"></a><spanclass="lineno"> 211</span> <spanclass="comment">// Adds an edge in the graph. Also adds both endpoint nodes as necessary.</span></div>
<divclass="line"><aname="l00212"></a><spanclass="lineno"> 212</span> <spanclass="comment">// It is not an error to add the same edge twice. Self-edges are OK too.</span></div>
<divclass="line"><aname="l00213"></a><spanclass="lineno"><aclass="line"href="class_connected_components_finder.html#a3e071f70e8c79a30a74cba46917630ec"> 213</a></span> <spanclass="keywordtype">void</span><aclass="code"href="class_connected_components_finder.html#a3e071f70e8c79a30a74cba46917630ec">AddEdge</a>(T node1, T node2) {</div>
<divclass="line"><aname="l00218"></a><spanclass="lineno"> 218</span> <spanclass="comment">// Returns true iff both nodes are in the same connected component.</span></div>
<divclass="line"><aname="l00219"></a><spanclass="lineno"> 219</span> <spanclass="comment">// Returns false if either node has not been already added with AddNode.</span></div>
<divclass="line"><aname="l00220"></a><spanclass="lineno"><aclass="line"href="class_connected_components_finder.html#ac7782f36c09257f370347166e02480f1"> 220</a></span> <spanclass="keywordtype">bool</span><aclass="code"href="class_connected_components_finder.html#ac7782f36c09257f370347166e02480f1">Connected</a>(T node1, T node2) {</div>
<divclass="line"><aname="l00225"></a><spanclass="lineno"> 225</span> <spanclass="comment">// Finds the connected component containing a node, and returns the</span></div>
<divclass="line"><aname="l00226"></a><spanclass="lineno"> 226</span> <spanclass="comment">// total number of nodes in that component. Returns zero iff the</span></div>
<divclass="line"><aname="l00227"></a><spanclass="lineno"> 227</span> <spanclass="comment">// node has not been already added with AddNode.</span></div>
<divclass="line"><aname="l00232"></a><spanclass="lineno"> 232</span> <spanclass="comment">// Finds all the connected components and assigns them to components.</span></div>
<divclass="line"><aname="l00233"></a><spanclass="lineno"> 233</span> <spanclass="comment">// Components are ordered in the same way nodes were added, i.e. if node 'b'</span></div>
<divclass="line"><aname="l00234"></a><spanclass="lineno"> 234</span> <spanclass="comment">// was added before node 'c', then either:</span></div>
<divclass="line"><aname="l00235"></a><spanclass="lineno"> 235</span> <spanclass="comment">// - 'c' belongs to the same component as a node 'a' added before 'b', or</span></div>
<divclass="line"><aname="l00236"></a><spanclass="lineno"> 236</span> <spanclass="comment">// - the component for 'c' comes after the one for 'b'.</span></div>
<divclass="line"><aname="l00237"></a><spanclass="lineno"> 237</span> <spanclass="comment">// There are two versions:</span></div>
<divclass="line"><aname="l00238"></a><spanclass="lineno"> 238</span> <spanclass="comment">// - The first one returns the result, and stores each component in a vector.</span></div>
<divclass="line"><aname="l00239"></a><spanclass="lineno"> 239</span> <spanclass="comment">// This is the preferred version.</span></div>
<divclass="line"><aname="l00240"></a><spanclass="lineno"> 240</span> <spanclass="comment">// - The second one populates the result, and stores each component in a set.</span></div>
<divclass="line"><aname="l00260"></a><spanclass="lineno"> 260</span> <spanclass="comment">// Returns the current number of connected components.</span></div>
<divclass="line"><aname="l00261"></a><spanclass="lineno"> 261</span> <spanclass="comment">// This number can change as the new nodes or edges are added.</span></div>
<divclass="line"><aname="l00266"></a><spanclass="lineno"> 266</span> <spanclass="comment">// Returns the current number of added distinct nodes.</span></div>
<divclass="line"><aname="l00267"></a><spanclass="lineno"> 267</span> <spanclass="comment">// This includes nodes added explicitly via the calls to AddNode() method</span></div>
<divclass="line"><aname="l00268"></a><spanclass="lineno"> 268</span> <spanclass="comment">// and implicitly via the calls to AddEdge() method.</span></div>
<divclass="line"><aname="l00269"></a><spanclass="lineno"> 269</span> <spanclass="comment">// Nodes that were added several times only count once.</span></div>
<divclass="line"><aname="l00273"></a><spanclass="lineno"> 273</span> <spanclass="comment">// Returns the index for the given node. If the node does not exist and</span></div>
<divclass="line"><aname="l00274"></a><spanclass="lineno"> 274</span> <spanclass="comment">// update_delegate is true, explicitly add the node to the delegate.</span></div>
<divclass="ttc"id="aclass_connected_components_finder_html_a3e071f70e8c79a30a74cba46917630ec"><divclass="ttname"><ahref="class_connected_components_finder.html#a3e071f70e8c79a30a74cba46917630ec">ConnectedComponentsFinder::AddEdge</a></div><divclass="ttdeci">void AddEdge(T node1, T node2)</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8h_source.html#l00213">connected_components.h:213</a></div></div>
<divclass="ttc"id="aclass_connected_components_finder_html_aa1ba612c449ee127c1e747851c56a5fd"><divclass="ttname"><ahref="class_connected_components_finder.html#aa1ba612c449ee127c1e747851c56a5fd">ConnectedComponentsFinder::FindConnectedComponents</a></div><divclass="ttdeci">std::vector< std::vector< T >> FindConnectedComponents()</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8h_source.html#l00241">connected_components.h:241</a></div></div>
<divclass="ttc"id="aclass_connected_components_finder_html_ac7782f36c09257f370347166e02480f1"><divclass="ttname"><ahref="class_connected_components_finder.html#ac7782f36c09257f370347166e02480f1">ConnectedComponentsFinder::Connected</a></div><divclass="ttdeci">bool Connected(T node1, T node2)</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8h_source.html#l00220">connected_components.h:220</a></div></div>
<divclass="ttc"id="aclass_connected_components_finder_html_afab44a2f4671e0d0b0f30268ee17b70a"><divclass="ttname"><ahref="class_connected_components_finder.html#afab44a2f4671e0d0b0f30268ee17b70a">ConnectedComponentsFinder::operator=</a></div><divclass="ttdeci">ConnectedComponentsFinder & operator=(const ConnectedComponentsFinder &)=delete</div></div>
<divclass="ttc"id="aclass_dense_connected_components_finder_html_a3bd75ea47488e500083fd8401d833f5d"><divclass="ttname"><ahref="class_dense_connected_components_finder.html#a3bd75ea47488e500083fd8401d833f5d">DenseConnectedComponentsFinder::AddEdge</a></div><divclass="ttdeci">void AddEdge(int node1, int node2)</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8cc_source.html#l00096">connected_components.cc:96</a></div></div>
<divclass="ttc"id="aclass_dense_connected_components_finder_html_a74aadb96adc6f37110393d5fbd2279c5"><divclass="ttname"><ahref="class_dense_connected_components_finder.html#a74aadb96adc6f37110393d5fbd2279c5">DenseConnectedComponentsFinder::GetComponentIds</a></div><divclass="ttdeci">std::vector< int > GetComponentIds()</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8cc_source.html#l00148">connected_components.cc:148</a></div></div>
<divclass="ttc"id="aclass_dense_connected_components_finder_html_a962b54327591b21cc0a9273f78906a8b"><divclass="ttname"><ahref="class_dense_connected_components_finder.html#a962b54327591b21cc0a9273f78906a8b">DenseConnectedComponentsFinder::Connected</a></div><divclass="ttdeci">bool Connected(int node1, int node2)</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8cc_source.html#l00133">connected_components.cc:133</a></div></div>
<divclass="ttc"id="aclass_dense_connected_components_finder_html_ae496b1d85aa3fde1d7090bac874bbdc4"><divclass="ttname"><ahref="class_dense_connected_components_finder.html#ae496b1d85aa3fde1d7090bac874bbdc4">DenseConnectedComponentsFinder::operator=</a></div><divclass="ttdeci">DenseConnectedComponentsFinder & operator=(const DenseConnectedComponentsFinder &)=delete</div></div>
<divclass="ttc"id="aclass_dense_connected_components_finder_html_ae6201f6f09303eabd7f77e238b4f3a44"><divclass="ttname"><ahref="class_dense_connected_components_finder.html#ae6201f6f09303eabd7f77e238b4f3a44">DenseConnectedComponentsFinder::GetComponentRoots</a></div><divclass="ttdeci">const std::vector< int >& GetComponentRoots()</div><divclass="ttdef"><b>Definition:</b><ahref="connected__components_8cc_source.html#l00073">connected_components.cc:73</a></div></div>