// maximum matchings in bipartite graphs// maximum cardinality bipartite matching// O(|V||E|), generally fast#include<algorithm>
#include<string>
#include<vector>usingnamespacestd;structHungarian{intnx,ny;vector<int>mx,my;vector<vector<int>>e;voidinit(intnx,intny){this->nx=nx;this->ny=ny;mx.resize(nx);my.resize(ny);e.clear();e.resize(nx);mark.resize(nx);}voidadd(inta,intb){e[a].push_back(b);}// vector<bool> is evil!!!basic_string<bool>mark;boolaugment(inti){if(!mark[i]){mark[i]=true;for(vector<int>::const_iteratorj=e[i].begin();j!=e[i].end();++j){if(my[*j]==-1||augment(my[*j])){mx[i]=*j;my[*j]=i;returntrue;}}}returnfalse;}intgao(){intret=0;fill(mx.begin(),mx.end(),-1);fill(my.begin(),my.end(),-1);for(inti=0;i<nx;++i){fill(mark.begin(),mark.end(),false);if(augment(i)){++ret;}}returnret;}};
#line 1 "src/watashi/bimatch.hpp"
// maximum matchings in bipartite graphs// maximum cardinality bipartite matching// O(|V||E|), generally fast#include<algorithm>
#include<string>
#include<vector>usingnamespacestd;structHungarian{intnx,ny;vector<int>mx,my;vector<vector<int>>e;voidinit(intnx,intny){this->nx=nx;this->ny=ny;mx.resize(nx);my.resize(ny);e.clear();e.resize(nx);mark.resize(nx);}voidadd(inta,intb){e[a].push_back(b);}// vector<bool> is evil!!!basic_string<bool>mark;boolaugment(inti){if(!mark[i]){mark[i]=true;for(vector<int>::const_iteratorj=e[i].begin();j!=e[i].end();++j){if(my[*j]==-1||augment(my[*j])){mx[i]=*j;my[*j]=i;returntrue;}}}returnfalse;}intgao(){intret=0;fill(mx.begin(),mx.end(),-1);fill(my.begin(),my.end(),-1);for(inti=0;i<nx;++i){fill(mark.begin(),mark.end(),false);if(augment(i)){++ret;}}returnret;}};