/* Copyright (c) 1997-2004 Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany) http://www.math.tu-berlin.de/polymake, mailto:polymake@math.tu-berlin.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version: http://www.gnu.org/licenses/gpl.txt. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #ifndef _POLYMAKE_GRAPH_CONNECTED_H #define _POLYMAKE_GRAPH_CONNECTED_H "$Project: polymake $$Id: connected.h 7315 2006-04-02 21:37:53Z gawrilow $" #include #include namespace polymake { namespace graph { /// Determine whether an undirected graph is connected. template bool is_connected(const Graph& G); template class ConnectedComponents_iterator { protected: const Graph *graph; Set component; Bitset not_visited; void get_next(); public: typedef std::forward_iterator_tag iterator_category; typedef Set value_type; typedef const value_type& reference; typedef const value_type* pointer; typedef ptrdiff_t difference_type; typedef ConnectedComponents_iterator iterator; typedef iterator const_iterator; ConnectedComponents_iterator() : graph(0) { } ConnectedComponents_iterator(const Graph& graph_arg); reference operator* () const { return component; } pointer operator-> () const { return &component; } iterator& operator++ () { component.clear(); get_next(); return *this; } const iterator operator++ (int) { iterator copy(*this); operator++(); return copy; } bool operator== (const iterator& it) const { return component==it.component; } bool operator!= (const iterator& it) const { return !operator==(it); } bool at_end() const { return component.empty(); } void rewind(); }; template class ConnectedComponents { protected: pm::alias graph; public: typedef typename pm::alias::arg_type arg_type; typedef typename pm::deref::type Graph; ConnectedComponents(arg_type graph_arg) : graph(graph_arg) { } typedef ConnectedComponents_iterator iterator; typedef iterator const_iterator; typedef typename iterator::value_type value_type; typedef const value_type reference; typedef reference const_reference; iterator begin() const { return iterator(graph); } iterator end() const { return iterator(); } reference front() const { return *begin(); } int size() const { return pm::count_it(begin()); } bool empty() const { return static_cast(graph).nodes()==0; } }; /// Compute the connected components template inline ConnectedComponents connected_components(const Graph& G) { return G; } } } namespace pm { template struct check_iterator_feature< polymake::graph::ConnectedComponents_iterator, end_sensitive > : True { }; template struct check_iterator_feature< polymake::graph::ConnectedComponents_iterator, rewindable > : True { }; template struct spec_object_traits< polymake::graph::ConnectedComponents > : spec_object_traits { }; } #include #endif // _POLYMAKE_GRAPH_CONNECTED_H // Local Variables: // mode:C++ // c-basic-offset:3 // End: