8 #include <unordered_map>
9 #include <unordered_set>
12 #include "andres/partition.hxx"
20 template<
typename GRAPH,
typename EVA,
typename ELA>
23 EVA
const& edge_values,
30 DynamicGraph(
size_t n) :
31 vertices_(n), cut_edges_(n)
34 bool edgeExists(
size_t a,
size_t b)
const
36 return !vertices_[a].empty() && vertices_[a].find(b) != vertices_[a].end();
39 std::unordered_map<size_t, typename EVA::value_type>
const& getAdjacentVertices(
size_t v)
const
44 typename EVA::value_type getEdgeWeight(
size_t a,
size_t b)
const
46 return vertices_[a].at(b);
49 bool isCutEdge(
size_t a,
size_t b)
const
51 return !cut_edges_[a].empty() && cut_edges_[a].find(b) != cut_edges_[a].end();
54 void markEdgeCut(
size_t a,
size_t b)
56 cut_edges_[a].insert(b);
57 cut_edges_[b].insert(a);
60 void removeVertex(
size_t v)
62 for (
auto& p : vertices_[v])
64 vertices_[p.first].erase(v);
65 cut_edges_[p.first].erase(v);
69 cut_edges_[v].clear();
72 void setEdgeWeight(
size_t a,
size_t b,
typename EVA::value_type w)
79 std::vector<std::unordered_set<size_t>> cut_edges_;
80 std::vector<std::unordered_map<size_t, typename EVA::value_type>> vertices_;
85 Edge(
size_t _a,
size_t _b,
typename EVA::value_type _w)
99 typename EVA::value_type w;
101 bool operator <(Edge
const& other)
const
103 return fabs(w) < fabs(other.w);
107 std::vector<std::unordered_map<size_t, size_t>> edge_editions(graph.numberOfVertices());
108 (graph.numberOfVertices());
110 DynamicGraph original_graph_cp(graph.numberOfVertices());
111 std::priority_queue<Edge> Q;
113 for (
size_t i = 0; i < graph.numberOfEdges(); ++i)
115 auto a = graph.vertexOfEdge(i, 0);
116 auto b = graph.vertexOfEdge(i, 1);
118 original_graph_cp.setEdgeWeight(a, b, edge_values[i]);
120 auto e = Edge(a, b, edge_values[i]);
121 e.edition = ++edge_editions[e.a][e.b];
126 andres::Partition<size_t> partition(graph.numberOfVertices());
133 if (!original_graph_cp.edgeExists(edge.a, edge.b) || edge.edition < edge_editions[edge.a][edge.b])
136 if (edge.w >
typename EVA::value_type() && !original_graph_cp.isCutEdge(edge.a, edge.b))
138 auto stable_vertex = edge.a;
139 auto merge_vertex = edge.b;
141 if (original_graph_cp.getAdjacentVertices(stable_vertex).size() < original_graph_cp.getAdjacentVertices(merge_vertex).size())
142 std::swap(stable_vertex, merge_vertex);
144 partition.merge(stable_vertex, merge_vertex);
146 for (
auto& p : original_graph_cp.getAdjacentVertices(merge_vertex))
148 if (p.first == stable_vertex)
151 typename EVA::value_type t =
typename EVA::value_type();
153 if (original_graph_cp.edgeExists(stable_vertex, p.first))
154 t = original_graph_cp.getEdgeWeight(stable_vertex, p.first);
156 if (original_graph_cp.isCutEdge(merge_vertex, p.first))
157 original_graph_cp.markEdgeCut(stable_vertex, p.first);
159 original_graph_cp.setEdgeWeight(stable_vertex, p.first, p.second + t);
161 auto e = Edge(stable_vertex, p.first, p.second + t);
162 e.edition = ++edge_editions[e.a][e.b];
167 original_graph_cp.removeVertex(merge_vertex);
169 else if (edge.w <
typename EVA::value_type())
170 original_graph_cp.markEdgeCut(edge.a, edge.b);
173 for (
size_t i = 0; i < graph.numberOfEdges(); ++i)
174 edge_labels[i] = partition.find(graph.vertexOfEdge(i, 0)) == partition.find(graph.vertexOfEdge(i, 1)) ? 0 : 1;