Kyopro Library
 
読み取り中…
検索中…
一致する文字列を見つけられません
bipartite_matching.hpp
[詳解]
1#include"../../kyopro_library/template.hpp"
2#include"../../kyopro_library/graph/flow/max_flow.hpp"
3
4/// @brief 二部グラフの最大マッチングを返す
5/// @note O(E*sqrt(V))
6/// @attention G は二部グラフであること
7vector<pair<int,int>> BipartiteMatching(const vector<vector<int>>& g) {
8 int n=g.size();
9 MaxFlow mxf(n+2);
10 int s=n,t=n+1;
11 for(int i=0; i<n; i++) {
12 for(int j:g[i]) mxf.add_edge(i,j,1);
13 mxf.add_edge(s,i,1);
14 mxf.add_edge(i,t,1);
15 }
16
17 mxf.flow(s,t);
18
19 vector<pair<int,int>> ret;
20 auto edges=mxf.get_edges();
21 for(auto& e:edges) {
22 if(e.from==s) continue;
23 if(e.to==t) continue;
24 if(e.flow==1) ret.push_back({e.from,e.to});
25 }
26
27 return ret;
28}
29
30/// @brief 二部グラフのパラメータ
31struct BiInfo {
32 int max_matching; ///< 最大マッチング
33 int min_edge_cover; ///< 最小辺被覆
34 int max_independent_set; ///< 最大独立集合
35 int min_vertex_cover; ///< 最小頂点被覆
36 /// @note min_edge_cover=-1 のときは孤立点がある
37};
38
39/// @brief 二部グラフのパラメータを求める
40/// @note O(E*sqrt(V))
41/// @attention G は二部グラフであること
42BiInfo GetBiInfo(const vector<vector<int>>& g) {
43 int n=g.size();
44 int isolation=0;
45 for(int i=0; i<n; i++) if(g[i].size()==0) isolation++;
46
47 BiInfo ret;
48 int m=BipartiteMatching(g).size();
49 ret.max_matching=m;
50 ret.min_edge_cover=isolation==0?n-m:-1;
53
54 return ret;
55}
BiInfo GetBiInfo(const vector< vector< int > > &g)
二部グラフのパラメータを求める
vector< pair< int, int > > BipartiteMatching(const vector< vector< int > > &g)
二部グラフの最大マッチングを返す
二部グラフのパラメータ
int max_matching
最大マッチング
int max_independent_set
最大独立集合
int min_edge_cover
最小辺被覆
最大流
Definition max_flow.hpp:5
MaxFlow(int n)
Definition max_flow.hpp:17
ll flow(int s, int t)
s から t への最大流を求める
Definition max_flow.hpp:63
void add_edge(int from, int to, ll cap)
容量 cap の辺を追加する
Definition max_flow.hpp:20