Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit 08ddaa1

Browse files
committed
MaximumBipartiteMatching.cpp
1 parent ee25801 commit 08ddaa1

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

MaximumBipartiteMatching.cpp

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_MaximumBipartiteMatching
22+
#endif
23+
24+
#ifndef FUNC_MaximumBipartiteMatching
25+
#define FUNC_MaximumBipartiteMatching
26+
27+
#include "utils.h"
28+
29+
#include "FordFulkerson.cpp"
30+
31+
template <typename GT>
32+
class Bipartite: public GT {
33+
public:
34+
using T = typename GT::vertix_type;
35+
Bipartite(bool direction): GT(direction) {}
36+
template <typename F1, typename F2>
37+
void graphviz(F1 f1, F2 f2) {
38+
if (GT::dir)
39+
std::cout << "digraph G {" << std::endl;
40+
else
41+
std::cout << "graph G {" << std::endl;
42+
std::cout << '\t';
43+
std::cout << "subgraph clusterL {\n\t";
44+
bool newline = true;
45+
for (auto i = L.begin(); i != L.end(); i++) {
46+
if (newline)
47+
std::cout << '\t';
48+
std::cout << *i;
49+
if (f1(*i)) {
50+
std::cout << "; \n\t";
51+
newline = true;
52+
} else {
53+
std::cout << "; ";
54+
newline = false;
55+
}
56+
}
57+
if (!newline)
58+
std::cout << "\n\t";
59+
std::cout << '}' << std::endl;
60+
std::cout << '\t';
61+
std::cout << "subgraph clusterR {\n\t";
62+
newline = true;
63+
for (auto i = R.begin(); i != R.end(); i++) {
64+
if (newline)
65+
std::cout << '\t';
66+
std::cout << *i;
67+
if (f1(*i)) {
68+
std::cout << "; \n\t";
69+
newline = true;
70+
} else {
71+
std::cout << "; ";
72+
newline = false;
73+
}
74+
}
75+
if (!newline)
76+
std::cout << "\n\t";
77+
std::cout << '}' << std::endl;
78+
for (auto i = GT::all_edges(); !i.end(); i++) {
79+
std::cout << '\t' << *i;
80+
f2(*i);
81+
std::cout << "; " << std::endl;
82+
}
83+
std::cout << "}" << std::endl;
84+
}
85+
void graphviz() {
86+
auto f1 = [](T v) { return false; };
87+
auto f2 = [](Edge<T> e) {};
88+
graphviz(f1, f2);
89+
}
90+
uset<T> L, R;
91+
};
92+
93+
template <typename GT, typename T>
94+
void random_bipartite(Bipartite<GT>& G, T vl, T vr, size_t e) {
95+
for (T i = 0; i < vl; i++) {
96+
G.add_vertex(i);
97+
G.L.insert(i);
98+
}
99+
for (T i = vl; i < vl + vr; i++) {
100+
G.add_vertex(i);
101+
G.R.insert(i);
102+
}
103+
std::vector<T> dl, dr;
104+
random_integers<T>(dl, 0, vl - 1, e);
105+
random_integers<T>(dr, vl, vl + vr - 1, e);
106+
for (size_t i = 0; i < e; i++)
107+
G.add_edge(dl[i], dr[i]);
108+
}
109+
110+
111+
template <typename GT, typename T>
112+
void MaximumBipartiteMatching(GT& G, uset<Edge<T>, EdgeHash<T>>& ans) {
113+
GraphAdjList<T> GF(true);
114+
umap<Edge<T>, T, EdgeHash<size_t>> c, f;
115+
T s = G.V.size(), t = s + 1;
116+
assert(G.V.find(s) == G.V.end() && G.V.find(t) == G.V.end());
117+
for (auto i = G.L.begin(); i != G.L.end(); i++) {
118+
GF.add_edge(s, *i);
119+
c[Edge<T>(s, *i, true)] = 1;
120+
}
121+
for (auto i = G.R.begin(); i != G.R.end(); i++) {
122+
GF.add_edge(*i, t);
123+
c[Edge<T>(*i, t, true)] = 1;
124+
}
125+
for (auto i = G.all_edges(); !i.end(); i++) {
126+
GF.add_edge(i.s(), i.d());
127+
c[Edge<T>(i.s(), i.d(), true)] = 1;
128+
}
129+
FordFulkerson(GF, c, s, t, f);
130+
for (auto i = G.all_edges(); !i.end(); i++)
131+
if (f[Edge<T>(i.s(), i.d(), true)])
132+
ans.insert(*i);
133+
}
134+
#endif
135+
136+
#ifdef MAIN_MaximumBipartiteMatching
137+
int main(int argc, char *argv[]) {
138+
const size_t vl = get_argv(argc, argv, 1, 5);
139+
const size_t vr = get_argv(argc, argv, 2, 5);
140+
const size_t e = get_argv(argc, argv, 3, 10);
141+
const bool dir = false;
142+
Bipartite<GraphAdjList<size_t>> G(dir);
143+
random_bipartite(G, vl, vr, e);
144+
uset<Edge<size_t>, EdgeHash<size_t>> ans;
145+
MaximumBipartiteMatching(G, ans);
146+
auto f1 = [](size_t v) { return false; };
147+
auto f2 = [ans](Edge<size_t> e) mutable {
148+
if (ans.find(e) != ans.end())
149+
std::cout << " [style=bold]";
150+
};
151+
G.graphviz(f1, f2);
152+
return 0;
153+
}
154+
#endif
155+

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@
165165
| 25 | TransitiveClosure.cpp | Transitive Closure | 698 |
166166
| 25 | Johnson.cpp | Johnson | 704 |
167167
| 26 | FordFulkerson.cpp | Ford Fulkerson | 724 |
168+
| 26 | MaximumBipartiteMatching.cpp | Maximum Bipartite Matching | 733 |
168169

169170
# Supplementary Files
170171
* `utils.h`: Utils

0 commit comments

Comments
 (0)