lemon/list_graph.h
changeset 1021 a12cca3ad15a
parent 877 141f9c0db4a3
child 1025 c8fa41fcc4a7
equal deleted inserted replaced
29:8182b909d421 30:1912fc6fd8b2
  1597       }
  1597       }
  1598     };
  1598     };
  1599   };
  1599   };
  1600 
  1600 
  1601   /// @}
  1601   /// @}
       
  1602 
       
  1603   class ListBpGraphBase {
       
  1604 
       
  1605   protected:
       
  1606 
       
  1607     struct NodeT {
       
  1608       int first_out;
       
  1609       int prev, next;
       
  1610       int partition_prev, partition_next;
       
  1611       int partition_index;
       
  1612       bool red;
       
  1613     };
       
  1614 
       
  1615     struct ArcT {
       
  1616       int target;
       
  1617       int prev_out, next_out;
       
  1618     };
       
  1619 
       
  1620     std::vector<NodeT> nodes;
       
  1621 
       
  1622     int first_node, first_red, first_blue;
       
  1623     int max_red, max_blue;
       
  1624 
       
  1625     int first_free_red, first_free_blue;
       
  1626 
       
  1627     std::vector<ArcT> arcs;
       
  1628 
       
  1629     int first_free_arc;
       
  1630 
       
  1631   public:
       
  1632 
       
  1633     typedef ListBpGraphBase BpGraph;
       
  1634 
       
  1635     class Node {
       
  1636       friend class ListBpGraphBase;
       
  1637     protected:
       
  1638 
       
  1639       int id;
       
  1640       explicit Node(int pid) { id = pid;}
       
  1641 
       
  1642     public:
       
  1643       Node() {}
       
  1644       Node (Invalid) { id = -1; }
       
  1645       bool operator==(const Node& node) const {return id == node.id;}
       
  1646       bool operator!=(const Node& node) const {return id != node.id;}
       
  1647       bool operator<(const Node& node) const {return id < node.id;}
       
  1648     };
       
  1649 
       
  1650     class Edge {
       
  1651       friend class ListBpGraphBase;
       
  1652     protected:
       
  1653 
       
  1654       int id;
       
  1655       explicit Edge(int pid) { id = pid;}
       
  1656 
       
  1657     public:
       
  1658       Edge() {}
       
  1659       Edge (Invalid) { id = -1; }
       
  1660       bool operator==(const Edge& edge) const {return id == edge.id;}
       
  1661       bool operator!=(const Edge& edge) const {return id != edge.id;}
       
  1662       bool operator<(const Edge& edge) const {return id < edge.id;}
       
  1663     };
       
  1664 
       
  1665     class Arc {
       
  1666       friend class ListBpGraphBase;
       
  1667     protected:
       
  1668 
       
  1669       int id;
       
  1670       explicit Arc(int pid) { id = pid;}
       
  1671 
       
  1672     public:
       
  1673       operator Edge() const {
       
  1674         return id != -1 ? edgeFromId(id / 2) : INVALID;
       
  1675       }
       
  1676 
       
  1677       Arc() {}
       
  1678       Arc (Invalid) { id = -1; }
       
  1679       bool operator==(const Arc& arc) const {return id == arc.id;}
       
  1680       bool operator!=(const Arc& arc) const {return id != arc.id;}
       
  1681       bool operator<(const Arc& arc) const {return id < arc.id;}
       
  1682     };
       
  1683 
       
  1684     ListBpGraphBase()
       
  1685       : nodes(), first_node(-1),
       
  1686         first_red(-1), first_blue(-1),
       
  1687         max_red(-1), max_blue(-1),
       
  1688         first_free_red(-1), first_free_blue(-1),
       
  1689         arcs(), first_free_arc(-1) {}
       
  1690 
       
  1691 
       
  1692     bool red(Node n) const { return nodes[n.id].red; }
       
  1693     bool blue(Node n) const { return !nodes[n.id].red; }
       
  1694 
       
  1695     int maxNodeId() const { return nodes.size()-1; }
       
  1696     int maxRedId() const { return max_red; }
       
  1697     int maxBlueId() const { return max_blue; }
       
  1698     int maxEdgeId() const { return arcs.size() / 2 - 1; }
       
  1699     int maxArcId() const { return arcs.size()-1; }
       
  1700 
       
  1701     Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
       
  1702     Node target(Arc e) const { return Node(arcs[e.id].target); }
       
  1703 
       
  1704     Node redNode(Edge e) const { return Node(arcs[2 * e.id].target); }
       
  1705     Node blueNode(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
       
  1706 
       
  1707     static bool direction(Arc e) {
       
  1708       return (e.id & 1) == 1;
       
  1709     }
       
  1710 
       
  1711     static Arc direct(Edge e, bool d) {
       
  1712       return Arc(e.id * 2 + (d ? 1 : 0));
       
  1713     }
       
  1714 
       
  1715     void first(Node& node) const {
       
  1716       node.id = first_node;
       
  1717     }
       
  1718 
       
  1719     void next(Node& node) const {
       
  1720       node.id = nodes[node.id].next;
       
  1721     }
       
  1722 
       
  1723     void firstRed(Node& node) const {
       
  1724       node.id = first_red;
       
  1725     }
       
  1726 
       
  1727     void nextRed(Node& node) const {
       
  1728       node.id = nodes[node.id].partition_next;
       
  1729     }
       
  1730 
       
  1731     void firstBlue(Node& node) const {
       
  1732       node.id = first_blue;
       
  1733     }
       
  1734 
       
  1735     void nextBlue(Node& node) const {
       
  1736       node.id = nodes[node.id].partition_next;
       
  1737     }    
       
  1738 
       
  1739     void first(Arc& e) const {
       
  1740       int n = first_node;
       
  1741       while (n != -1 && nodes[n].first_out == -1) {
       
  1742         n = nodes[n].next;
       
  1743       }
       
  1744       e.id = (n == -1) ? -1 : nodes[n].first_out;
       
  1745     }
       
  1746 
       
  1747     void next(Arc& e) const {
       
  1748       if (arcs[e.id].next_out != -1) {
       
  1749         e.id = arcs[e.id].next_out;
       
  1750       } else {
       
  1751         int n = nodes[arcs[e.id ^ 1].target].next;
       
  1752         while(n != -1 && nodes[n].first_out == -1) {
       
  1753           n = nodes[n].next;
       
  1754         }
       
  1755         e.id = (n == -1) ? -1 : nodes[n].first_out;
       
  1756       }
       
  1757     }
       
  1758 
       
  1759     void first(Edge& e) const {
       
  1760       int n = first_node;
       
  1761       while (n != -1) {
       
  1762         e.id = nodes[n].first_out;
       
  1763         while ((e.id & 1) != 1) {
       
  1764           e.id = arcs[e.id].next_out;
       
  1765         }
       
  1766         if (e.id != -1) {
       
  1767           e.id /= 2;
       
  1768           return;
       
  1769         }
       
  1770         n = nodes[n].next;
       
  1771       }
       
  1772       e.id = -1;
       
  1773     }
       
  1774 
       
  1775     void next(Edge& e) const {
       
  1776       int n = arcs[e.id * 2].target;
       
  1777       e.id = arcs[(e.id * 2) | 1].next_out;
       
  1778       while ((e.id & 1) != 1) {
       
  1779         e.id = arcs[e.id].next_out;
       
  1780       }
       
  1781       if (e.id != -1) {
       
  1782         e.id /= 2;
       
  1783         return;
       
  1784       }
       
  1785       n = nodes[n].next;
       
  1786       while (n != -1) {
       
  1787         e.id = nodes[n].first_out;
       
  1788         while ((e.id & 1) != 1) {
       
  1789           e.id = arcs[e.id].next_out;
       
  1790         }
       
  1791         if (e.id != -1) {
       
  1792           e.id /= 2;
       
  1793           return;
       
  1794         }
       
  1795         n = nodes[n].next;
       
  1796       }
       
  1797       e.id = -1;
       
  1798     }
       
  1799 
       
  1800     void firstOut(Arc &e, const Node& v) const {
       
  1801       e.id = nodes[v.id].first_out;
       
  1802     }
       
  1803     void nextOut(Arc &e) const {
       
  1804       e.id = arcs[e.id].next_out;
       
  1805     }
       
  1806 
       
  1807     void firstIn(Arc &e, const Node& v) const {
       
  1808       e.id = ((nodes[v.id].first_out) ^ 1);
       
  1809       if (e.id == -2) e.id = -1;
       
  1810     }
       
  1811     void nextIn(Arc &e) const {
       
  1812       e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
       
  1813       if (e.id == -2) e.id = -1;
       
  1814     }
       
  1815 
       
  1816     void firstInc(Edge &e, bool& d, const Node& v) const {
       
  1817       int a = nodes[v.id].first_out;
       
  1818       if (a != -1 ) {
       
  1819         e.id = a / 2;
       
  1820         d = ((a & 1) == 1);
       
  1821       } else {
       
  1822         e.id = -1;
       
  1823         d = true;
       
  1824       }
       
  1825     }
       
  1826     void nextInc(Edge &e, bool& d) const {
       
  1827       int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
       
  1828       if (a != -1 ) {
       
  1829         e.id = a / 2;
       
  1830         d = ((a & 1) == 1);
       
  1831       } else {
       
  1832         e.id = -1;
       
  1833         d = true;
       
  1834       }
       
  1835     }
       
  1836 
       
  1837     static int id(Node v) { return v.id; }
       
  1838     int redId(Node v) const {
       
  1839       LEMON_DEBUG(nodes[v.id].red, "Node has to be red");
       
  1840       return nodes[v.id].partition_index;
       
  1841     }
       
  1842     int blueId(Node v) const {
       
  1843       LEMON_DEBUG(!nodes[v.id].red, "Node has to be blue");
       
  1844       return nodes[v.id].partition_index;
       
  1845     }
       
  1846     static int id(Arc e) { return e.id; }
       
  1847     static int id(Edge e) { return e.id; }
       
  1848 
       
  1849     static Node nodeFromId(int id) { return Node(id);}
       
  1850     static Arc arcFromId(int id) { return Arc(id);}
       
  1851     static Edge edgeFromId(int id) { return Edge(id);}
       
  1852 
       
  1853     bool valid(Node n) const {
       
  1854       return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
       
  1855         nodes[n.id].prev != -2;
       
  1856     }
       
  1857 
       
  1858     bool valid(Arc a) const {
       
  1859       return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
       
  1860         arcs[a.id].prev_out != -2;
       
  1861     }
       
  1862 
       
  1863     bool valid(Edge e) const {
       
  1864       return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
       
  1865         arcs[2 * e.id].prev_out != -2;
       
  1866     }
       
  1867 
       
  1868     Node addRedNode() {
       
  1869       int n;
       
  1870 
       
  1871       if(first_free_red==-1) {
       
  1872         n = nodes.size();
       
  1873         nodes.push_back(NodeT());
       
  1874         nodes[n].partition_index = ++max_red;
       
  1875         nodes[n].red = true;
       
  1876       } else {
       
  1877         n = first_free_red;
       
  1878         first_free_red = nodes[n].next;
       
  1879       }
       
  1880 
       
  1881       nodes[n].next = first_node;
       
  1882       if (first_node != -1) nodes[first_node].prev = n;
       
  1883       first_node = n;
       
  1884       nodes[n].prev = -1;
       
  1885 
       
  1886       nodes[n].partition_next = first_red;
       
  1887       if (first_red != -1) nodes[first_red].partition_prev = n;
       
  1888       first_red = n;
       
  1889       nodes[n].partition_prev = -1;
       
  1890 
       
  1891       nodes[n].first_out = -1;
       
  1892 
       
  1893       return Node(n);
       
  1894     }
       
  1895 
       
  1896     Node addBlueNode() {
       
  1897       int n;
       
  1898 
       
  1899       if(first_free_blue==-1) {
       
  1900         n = nodes.size();
       
  1901         nodes.push_back(NodeT());
       
  1902         nodes[n].partition_index = ++max_blue;
       
  1903         nodes[n].red = false;
       
  1904       } else {
       
  1905         n = first_free_blue;
       
  1906         first_free_blue = nodes[n].next;
       
  1907       }
       
  1908 
       
  1909       nodes[n].next = first_node;
       
  1910       if (first_node != -1) nodes[first_node].prev = n;
       
  1911       first_node = n;
       
  1912       nodes[n].prev = -1;
       
  1913 
       
  1914       nodes[n].partition_next = first_blue;
       
  1915       if (first_blue != -1) nodes[first_blue].partition_prev = n;
       
  1916       first_blue = n;
       
  1917       nodes[n].partition_prev = -1;
       
  1918 
       
  1919       nodes[n].first_out = -1;
       
  1920 
       
  1921       return Node(n);
       
  1922     }
       
  1923 
       
  1924     Edge addEdge(Node u, Node v) {
       
  1925       int n;
       
  1926 
       
  1927       if (first_free_arc == -1) {
       
  1928         n = arcs.size();
       
  1929         arcs.push_back(ArcT());
       
  1930         arcs.push_back(ArcT());
       
  1931       } else {
       
  1932         n = first_free_arc;
       
  1933         first_free_arc = arcs[n].next_out;
       
  1934       }
       
  1935 
       
  1936       arcs[n].target = u.id;
       
  1937       arcs[n | 1].target = v.id;
       
  1938 
       
  1939       arcs[n].next_out = nodes[v.id].first_out;
       
  1940       if (nodes[v.id].first_out != -1) {
       
  1941         arcs[nodes[v.id].first_out].prev_out = n;
       
  1942       }
       
  1943       arcs[n].prev_out = -1;
       
  1944       nodes[v.id].first_out = n;
       
  1945 
       
  1946       arcs[n | 1].next_out = nodes[u.id].first_out;
       
  1947       if (nodes[u.id].first_out != -1) {
       
  1948         arcs[nodes[u.id].first_out].prev_out = (n | 1);
       
  1949       }
       
  1950       arcs[n | 1].prev_out = -1;
       
  1951       nodes[u.id].first_out = (n | 1);
       
  1952 
       
  1953       return Edge(n / 2);
       
  1954     }
       
  1955 
       
  1956     void erase(const Node& node) {
       
  1957       int n = node.id;
       
  1958 
       
  1959       if(nodes[n].next != -1) {
       
  1960         nodes[nodes[n].next].prev = nodes[n].prev;
       
  1961       }
       
  1962 
       
  1963       if(nodes[n].prev != -1) {
       
  1964         nodes[nodes[n].prev].next = nodes[n].next;
       
  1965       } else {
       
  1966         first_node = nodes[n].next;
       
  1967       }
       
  1968 
       
  1969       if (nodes[n].partition_next != -1) {
       
  1970         nodes[nodes[n].partition_next].partition_prev = nodes[n].partition_prev;
       
  1971       }
       
  1972 
       
  1973       if (nodes[n].partition_prev != -1) {
       
  1974         nodes[nodes[n].partition_prev].partition_next = nodes[n].partition_next;
       
  1975       } else {
       
  1976         if (nodes[n].red) {
       
  1977           first_red = nodes[n].partition_next;
       
  1978         } else {
       
  1979           first_blue = nodes[n].partition_next;
       
  1980         }
       
  1981       }
       
  1982 
       
  1983       if (nodes[n].red) {
       
  1984         nodes[n].next = first_free_red;
       
  1985         first_free_red = n;
       
  1986       } else {
       
  1987         nodes[n].next = first_free_blue;
       
  1988         first_free_blue = n;
       
  1989       }
       
  1990       nodes[n].prev = -2;
       
  1991     }
       
  1992 
       
  1993     void erase(const Edge& edge) {
       
  1994       int n = edge.id * 2;
       
  1995 
       
  1996       if (arcs[n].next_out != -1) {
       
  1997         arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
       
  1998       }
       
  1999 
       
  2000       if (arcs[n].prev_out != -1) {
       
  2001         arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
       
  2002       } else {
       
  2003         nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
       
  2004       }
       
  2005 
       
  2006       if (arcs[n | 1].next_out != -1) {
       
  2007         arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
       
  2008       }
       
  2009 
       
  2010       if (arcs[n | 1].prev_out != -1) {
       
  2011         arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
       
  2012       } else {
       
  2013         nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
       
  2014       }
       
  2015 
       
  2016       arcs[n].next_out = first_free_arc;
       
  2017       first_free_arc = n;
       
  2018       arcs[n].prev_out = -2;
       
  2019       arcs[n | 1].prev_out = -2;
       
  2020 
       
  2021     }
       
  2022 
       
  2023     void clear() {
       
  2024       arcs.clear();
       
  2025       nodes.clear();
       
  2026       first_node = first_free_arc = first_red = first_blue =
       
  2027         max_red = max_blue = first_free_red = first_free_blue = -1;
       
  2028     }
       
  2029 
       
  2030   protected:
       
  2031 
       
  2032     void changeRed(Edge e, Node n) {
       
  2033       LEMON_DEBUG(nodes[n].red, "Node has to be red");
       
  2034       if(arcs[(2 * e.id) | 1].next_out != -1) {
       
  2035         arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
       
  2036           arcs[(2 * e.id) | 1].prev_out;
       
  2037       }
       
  2038       if(arcs[(2 * e.id) | 1].prev_out != -1) {
       
  2039         arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
       
  2040           arcs[(2 * e.id) | 1].next_out;
       
  2041       } else {
       
  2042         nodes[arcs[2 * e.id].target].first_out =
       
  2043           arcs[(2 * e.id) | 1].next_out;
       
  2044       }
       
  2045 
       
  2046       if (nodes[n.id].first_out != -1) {
       
  2047         arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
       
  2048       }
       
  2049       arcs[2 * e.id].target = n.id;
       
  2050       arcs[(2 * e.id) | 1].prev_out = -1;
       
  2051       arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
       
  2052       nodes[n.id].first_out = ((2 * e.id) | 1);
       
  2053     }
       
  2054 
       
  2055     void changeBlue(Edge e, Node n) {
       
  2056       LEMON_DEBUG(nodes[n].red, "Node has to be blue");
       
  2057       if(arcs[2 * e.id].next_out != -1) {
       
  2058         arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
       
  2059       }
       
  2060       if(arcs[2 * e.id].prev_out != -1) {
       
  2061         arcs[arcs[2 * e.id].prev_out].next_out =
       
  2062           arcs[2 * e.id].next_out;
       
  2063       } else {
       
  2064         nodes[arcs[(2 * e.id) | 1].target].first_out =
       
  2065           arcs[2 * e.id].next_out;
       
  2066       }
       
  2067 
       
  2068       if (nodes[n.id].first_out != -1) {
       
  2069         arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
       
  2070       }
       
  2071       arcs[(2 * e.id) | 1].target = n.id;
       
  2072       arcs[2 * e.id].prev_out = -1;
       
  2073       arcs[2 * e.id].next_out = nodes[n.id].first_out;
       
  2074       nodes[n.id].first_out = 2 * e.id;
       
  2075     }
       
  2076 
       
  2077   };
       
  2078 
       
  2079   typedef BpGraphExtender<ListBpGraphBase> ExtendedListBpGraphBase;
       
  2080 
       
  2081 
       
  2082   /// \addtogroup graphs
       
  2083   /// @{
       
  2084 
       
  2085   ///A general undirected graph structure.
       
  2086 
       
  2087   ///\ref ListBpGraph is a versatile and fast undirected graph
       
  2088   ///implementation based on linked lists that are stored in
       
  2089   ///\c std::vector structures.
       
  2090   ///
       
  2091   ///This type fully conforms to the \ref concepts::BpGraph "BpGraph concept"
       
  2092   ///and it also provides several useful additional functionalities.
       
  2093   ///Most of its member functions and nested classes are documented
       
  2094   ///only in the concept class.
       
  2095   ///
       
  2096   ///This class provides only linear time counting for nodes, edges and arcs.
       
  2097   ///
       
  2098   ///\sa concepts::BpGraph
       
  2099   ///\sa ListDigraph
       
  2100   class ListBpGraph : public ExtendedListBpGraphBase {
       
  2101     typedef ExtendedListBpGraphBase Parent;
       
  2102 
       
  2103   private:
       
  2104     /// BpGraphs are \e not copy constructible. Use BpGraphCopy instead.
       
  2105     ListBpGraph(const ListBpGraph &) :ExtendedListBpGraphBase()  {};
       
  2106     /// \brief Assignment of a graph to another one is \e not allowed.
       
  2107     /// Use BpGraphCopy instead.
       
  2108     void operator=(const ListBpGraph &) {}
       
  2109   public:
       
  2110     /// Constructor
       
  2111 
       
  2112     /// Constructor.
       
  2113     ///
       
  2114     ListBpGraph() {}
       
  2115 
       
  2116     typedef Parent::OutArcIt IncEdgeIt;
       
  2117 
       
  2118     /// \brief Add a new red node to the graph.
       
  2119     ///
       
  2120     /// This function adds a red new node to the graph.
       
  2121     /// \return The new node.
       
  2122     Node addRedNode() { return Parent::addRedNode(); }
       
  2123 
       
  2124     /// \brief Add a new blue node to the graph.
       
  2125     ///
       
  2126     /// This function adds a blue new node to the graph.
       
  2127     /// \return The new node.
       
  2128     Node addBlueNode() { return Parent::addBlueNode(); }
       
  2129 
       
  2130     /// \brief Add a new edge to the graph.
       
  2131     ///
       
  2132     /// This function adds a new edge to the graph between nodes
       
  2133     /// \c u and \c v with inherent orientation from node \c u to
       
  2134     /// node \c v.
       
  2135     /// \return The new edge.
       
  2136     Edge addEdge(Node u, Node v) {
       
  2137       return Parent::addEdge(u, v);
       
  2138     }
       
  2139 
       
  2140     ///\brief Erase a node from the graph.
       
  2141     ///
       
  2142     /// This function erases the given node along with its incident arcs
       
  2143     /// from the graph.
       
  2144     ///
       
  2145     /// \note All iterators referencing the removed node or the incident
       
  2146     /// edges are invalidated, of course.
       
  2147     void erase(Node n) { Parent::erase(n); }
       
  2148 
       
  2149     ///\brief Erase an edge from the graph.
       
  2150     ///
       
  2151     /// This function erases the given edge from the graph.
       
  2152     ///
       
  2153     /// \note All iterators referencing the removed edge are invalidated,
       
  2154     /// of course.
       
  2155     void erase(Edge e) { Parent::erase(e); }
       
  2156     /// Node validity check
       
  2157 
       
  2158     /// This function gives back \c true if the given node is valid,
       
  2159     /// i.e. it is a real node of the graph.
       
  2160     ///
       
  2161     /// \warning A removed node could become valid again if new nodes are
       
  2162     /// added to the graph.
       
  2163     bool valid(Node n) const { return Parent::valid(n); }
       
  2164     /// Edge validity check
       
  2165 
       
  2166     /// This function gives back \c true if the given edge is valid,
       
  2167     /// i.e. it is a real edge of the graph.
       
  2168     ///
       
  2169     /// \warning A removed edge could become valid again if new edges are
       
  2170     /// added to the graph.
       
  2171     bool valid(Edge e) const { return Parent::valid(e); }
       
  2172     /// Arc validity check
       
  2173 
       
  2174     /// This function gives back \c true if the given arc is valid,
       
  2175     /// i.e. it is a real arc of the graph.
       
  2176     ///
       
  2177     /// \warning A removed arc could become valid again if new edges are
       
  2178     /// added to the graph.
       
  2179     bool valid(Arc a) const { return Parent::valid(a); }
       
  2180 
       
  2181     /// \brief Change the red node of an edge.
       
  2182     ///
       
  2183     /// This function changes the red node of the given edge \c e to \c n.
       
  2184     ///
       
  2185     ///\note \c EdgeIt and \c ArcIt iterators referencing the
       
  2186     ///changed edge are invalidated and all other iterators whose
       
  2187     ///base node is the changed node are also invalidated.
       
  2188     ///
       
  2189     ///\warning This functionality cannot be used together with the
       
  2190     ///Snapshot feature.
       
  2191     void changeRed(Edge e, Node n) {
       
  2192       Parent::changeRed(e,n);
       
  2193     }
       
  2194     /// \brief Change the blue node of an edge.
       
  2195     ///
       
  2196     /// This function changes the blue node of the given edge \c e to \c n.
       
  2197     ///
       
  2198     ///\note \c EdgeIt iterators referencing the changed edge remain
       
  2199     ///valid, but \c ArcIt iterators referencing the changed edge and
       
  2200     ///all other iterators whose base node is the changed node are also
       
  2201     ///invalidated.
       
  2202     ///
       
  2203     ///\warning This functionality cannot be used together with the
       
  2204     ///Snapshot feature.
       
  2205     void changeBlue(Edge e, Node n) {
       
  2206       Parent::changeBlue(e,n);
       
  2207     }
       
  2208 
       
  2209     ///Clear the graph.
       
  2210 
       
  2211     ///This function erases all nodes and arcs from the graph.
       
  2212     ///
       
  2213     ///\note All iterators of the graph are invalidated, of course.
       
  2214     void clear() {
       
  2215       Parent::clear();
       
  2216     }
       
  2217 
       
  2218     /// Reserve memory for nodes.
       
  2219 
       
  2220     /// Using this function, it is possible to avoid superfluous memory
       
  2221     /// allocation: if you know that the graph you want to build will
       
  2222     /// be large (e.g. it will contain millions of nodes and/or edges),
       
  2223     /// then it is worth reserving space for this amount before starting
       
  2224     /// to build the graph.
       
  2225     /// \sa reserveEdge()
       
  2226     void reserveNode(int n) { nodes.reserve(n); };
       
  2227 
       
  2228     /// Reserve memory for edges.
       
  2229 
       
  2230     /// Using this function, it is possible to avoid superfluous memory
       
  2231     /// allocation: if you know that the graph you want to build will
       
  2232     /// be large (e.g. it will contain millions of nodes and/or edges),
       
  2233     /// then it is worth reserving space for this amount before starting
       
  2234     /// to build the graph.
       
  2235     /// \sa reserveNode()
       
  2236     void reserveEdge(int m) { arcs.reserve(2 * m); };
       
  2237 
       
  2238     /// \brief Class to make a snapshot of the graph and restore
       
  2239     /// it later.
       
  2240     ///
       
  2241     /// Class to make a snapshot of the graph and restore it later.
       
  2242     ///
       
  2243     /// The newly added nodes and edges can be removed
       
  2244     /// using the restore() function.
       
  2245     ///
       
  2246     /// \note After a state is restored, you cannot restore a later state,
       
  2247     /// i.e. you cannot add the removed nodes and edges again using
       
  2248     /// another Snapshot instance.
       
  2249     ///
       
  2250     /// \warning Node and edge deletions and other modifications
       
  2251     /// (e.g. changing the end-nodes of edges or contracting nodes)
       
  2252     /// cannot be restored. These events invalidate the snapshot.
       
  2253     /// However, the edges and nodes that were added to the graph after
       
  2254     /// making the current snapshot can be removed without invalidating it.
       
  2255     class Snapshot {
       
  2256     protected:
       
  2257 
       
  2258       typedef Parent::NodeNotifier NodeNotifier;
       
  2259 
       
  2260       class NodeObserverProxy : public NodeNotifier::ObserverBase {
       
  2261       public:
       
  2262 
       
  2263         NodeObserverProxy(Snapshot& _snapshot)
       
  2264           : snapshot(_snapshot) {}
       
  2265 
       
  2266         using NodeNotifier::ObserverBase::attach;
       
  2267         using NodeNotifier::ObserverBase::detach;
       
  2268         using NodeNotifier::ObserverBase::attached;
       
  2269 
       
  2270       protected:
       
  2271 
       
  2272         virtual void add(const Node& node) {
       
  2273           snapshot.addNode(node);
       
  2274         }
       
  2275         virtual void add(const std::vector<Node>& nodes) {
       
  2276           for (int i = nodes.size() - 1; i >= 0; ++i) {
       
  2277             snapshot.addNode(nodes[i]);
       
  2278           }
       
  2279         }
       
  2280         virtual void erase(const Node& node) {
       
  2281           snapshot.eraseNode(node);
       
  2282         }
       
  2283         virtual void erase(const std::vector<Node>& nodes) {
       
  2284           for (int i = 0; i < int(nodes.size()); ++i) {
       
  2285             snapshot.eraseNode(nodes[i]);
       
  2286           }
       
  2287         }
       
  2288         virtual void build() {
       
  2289           Node node;
       
  2290           std::vector<Node> nodes;
       
  2291           for (notifier()->first(node); node != INVALID;
       
  2292                notifier()->next(node)) {
       
  2293             nodes.push_back(node);
       
  2294           }
       
  2295           for (int i = nodes.size() - 1; i >= 0; --i) {
       
  2296             snapshot.addNode(nodes[i]);
       
  2297           }
       
  2298         }
       
  2299         virtual void clear() {
       
  2300           Node node;
       
  2301           for (notifier()->first(node); node != INVALID;
       
  2302                notifier()->next(node)) {
       
  2303             snapshot.eraseNode(node);
       
  2304           }
       
  2305         }
       
  2306 
       
  2307         Snapshot& snapshot;
       
  2308       };
       
  2309 
       
  2310       class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
       
  2311       public:
       
  2312 
       
  2313         EdgeObserverProxy(Snapshot& _snapshot)
       
  2314           : snapshot(_snapshot) {}
       
  2315 
       
  2316         using EdgeNotifier::ObserverBase::attach;
       
  2317         using EdgeNotifier::ObserverBase::detach;
       
  2318         using EdgeNotifier::ObserverBase::attached;
       
  2319 
       
  2320       protected:
       
  2321 
       
  2322         virtual void add(const Edge& edge) {
       
  2323           snapshot.addEdge(edge);
       
  2324         }
       
  2325         virtual void add(const std::vector<Edge>& edges) {
       
  2326           for (int i = edges.size() - 1; i >= 0; ++i) {
       
  2327             snapshot.addEdge(edges[i]);
       
  2328           }
       
  2329         }
       
  2330         virtual void erase(const Edge& edge) {
       
  2331           snapshot.eraseEdge(edge);
       
  2332         }
       
  2333         virtual void erase(const std::vector<Edge>& edges) {
       
  2334           for (int i = 0; i < int(edges.size()); ++i) {
       
  2335             snapshot.eraseEdge(edges[i]);
       
  2336           }
       
  2337         }
       
  2338         virtual void build() {
       
  2339           Edge edge;
       
  2340           std::vector<Edge> edges;
       
  2341           for (notifier()->first(edge); edge != INVALID;
       
  2342                notifier()->next(edge)) {
       
  2343             edges.push_back(edge);
       
  2344           }
       
  2345           for (int i = edges.size() - 1; i >= 0; --i) {
       
  2346             snapshot.addEdge(edges[i]);
       
  2347           }
       
  2348         }
       
  2349         virtual void clear() {
       
  2350           Edge edge;
       
  2351           for (notifier()->first(edge); edge != INVALID;
       
  2352                notifier()->next(edge)) {
       
  2353             snapshot.eraseEdge(edge);
       
  2354           }
       
  2355         }
       
  2356 
       
  2357         Snapshot& snapshot;
       
  2358       };
       
  2359 
       
  2360       ListBpGraph *graph;
       
  2361 
       
  2362       NodeObserverProxy node_observer_proxy;
       
  2363       EdgeObserverProxy edge_observer_proxy;
       
  2364 
       
  2365       std::list<Node> added_nodes;
       
  2366       std::list<Edge> added_edges;
       
  2367 
       
  2368 
       
  2369       void addNode(const Node& node) {
       
  2370         added_nodes.push_front(node);
       
  2371       }
       
  2372       void eraseNode(const Node& node) {
       
  2373         std::list<Node>::iterator it =
       
  2374           std::find(added_nodes.begin(), added_nodes.end(), node);
       
  2375         if (it == added_nodes.end()) {
       
  2376           clear();
       
  2377           edge_observer_proxy.detach();
       
  2378           throw NodeNotifier::ImmediateDetach();
       
  2379         } else {
       
  2380           added_nodes.erase(it);
       
  2381         }
       
  2382       }
       
  2383 
       
  2384       void addEdge(const Edge& edge) {
       
  2385         added_edges.push_front(edge);
       
  2386       }
       
  2387       void eraseEdge(const Edge& edge) {
       
  2388         std::list<Edge>::iterator it =
       
  2389           std::find(added_edges.begin(), added_edges.end(), edge);
       
  2390         if (it == added_edges.end()) {
       
  2391           clear();
       
  2392           node_observer_proxy.detach();
       
  2393           throw EdgeNotifier::ImmediateDetach();
       
  2394         } else {
       
  2395           added_edges.erase(it);
       
  2396         }
       
  2397       }
       
  2398 
       
  2399       void attach(ListBpGraph &_graph) {
       
  2400         graph = &_graph;
       
  2401         node_observer_proxy.attach(graph->notifier(Node()));
       
  2402         edge_observer_proxy.attach(graph->notifier(Edge()));
       
  2403       }
       
  2404 
       
  2405       void detach() {
       
  2406         node_observer_proxy.detach();
       
  2407         edge_observer_proxy.detach();
       
  2408       }
       
  2409 
       
  2410       bool attached() const {
       
  2411         return node_observer_proxy.attached();
       
  2412       }
       
  2413 
       
  2414       void clear() {
       
  2415         added_nodes.clear();
       
  2416         added_edges.clear();
       
  2417       }
       
  2418 
       
  2419     public:
       
  2420 
       
  2421       /// \brief Default constructor.
       
  2422       ///
       
  2423       /// Default constructor.
       
  2424       /// You have to call save() to actually make a snapshot.
       
  2425       Snapshot()
       
  2426         : graph(0), node_observer_proxy(*this),
       
  2427           edge_observer_proxy(*this) {}
       
  2428 
       
  2429       /// \brief Constructor that immediately makes a snapshot.
       
  2430       ///
       
  2431       /// This constructor immediately makes a snapshot of the given graph.
       
  2432       Snapshot(ListBpGraph &gr)
       
  2433         : node_observer_proxy(*this),
       
  2434           edge_observer_proxy(*this) {
       
  2435         attach(gr);
       
  2436       }
       
  2437 
       
  2438       /// \brief Make a snapshot.
       
  2439       ///
       
  2440       /// This function makes a snapshot of the given graph.
       
  2441       /// It can be called more than once. In case of a repeated
       
  2442       /// call, the previous snapshot gets lost.
       
  2443       void save(ListBpGraph &gr) {
       
  2444         if (attached()) {
       
  2445           detach();
       
  2446           clear();
       
  2447         }
       
  2448         attach(gr);
       
  2449       }
       
  2450 
       
  2451       /// \brief Undo the changes until the last snapshot.
       
  2452       ///
       
  2453       /// This function undos the changes until the last snapshot
       
  2454       /// created by save() or Snapshot(ListBpGraph&).
       
  2455       ///
       
  2456       /// \warning This method invalidates the snapshot, i.e. repeated
       
  2457       /// restoring is not supported unless you call save() again.
       
  2458       void restore() {
       
  2459         detach();
       
  2460         for(std::list<Edge>::iterator it = added_edges.begin();
       
  2461             it != added_edges.end(); ++it) {
       
  2462           graph->erase(*it);
       
  2463         }
       
  2464         for(std::list<Node>::iterator it = added_nodes.begin();
       
  2465             it != added_nodes.end(); ++it) {
       
  2466           graph->erase(*it);
       
  2467         }
       
  2468         clear();
       
  2469       }
       
  2470 
       
  2471       /// \brief Returns \c true if the snapshot is valid.
       
  2472       ///
       
  2473       /// This function returns \c true if the snapshot is valid.
       
  2474       bool valid() const {
       
  2475         return attached();
       
  2476       }
       
  2477     };
       
  2478   };
       
  2479 
       
  2480   /// @}
  1602 } //namespace lemon
  2481 } //namespace lemon
  1603 
  2482 
  1604 
  2483 
  1605 #endif
  2484 #endif