二分图匹配模板
二分图匹配模板
匈牙利算法
时间复杂度:O(n*m)
const int MAXN=405;
int G[MAXN][MAXN];
int vis[MAXN];
int pre[MAXN];
int N;
int findpath(int cur)
{
for(int i=1; i<=N; ++i)
{
if(!vis[i]&&G[cur][i])
{
vis[i] = true;
if(pre[i] == 0 || findpath(pre[i]))
{
pre[i]=cur;
return 1;
}
}
}
return 0;
}
int Maxmatch()
{
int res = 0;
memset(pre,0,sizeof(pre));
for(int i=1;i<=N;++i)
{
memset(vis,0,sizeof(vis));
if(findpath(i))
res++;
}
return res;
}
Hopcraft-Karp算法
时间复杂度:O(n^0.5*m)
const int MAXN = 3010;
const int INF = 1<<30;
int G[MAXN][MAXN];
int cx[MAXN],cy[MAXN];
int dx[MAXN],dy[MAXN];
int vis[MAXN];
int nx,ny,dis;
bool searchpath()
{
queue<int>Q;
dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=1;i<=nx;i++){
if(cx[i]==-1){
Q.push(i);
dx[i]=0;
}
}
while(!Q.empty()){
int u=Q.front();
Q.pop();
if(dx[u]>dis) break;
for(int v=1;v<=ny;v++){
if(G[u][v]&&dy[v]==-1){
dy[v]=dx[u]+1;
if(cy[v]==-1) dis=dy[v];
else{
dx[cy[v]]=dy[v]+1;
Q.push(cy[v]);
}
}
}
}
return dis!=INF;
}
int findpath(int u)
{
for(int v=1;v<=ny;v++){
if(!vis[v]&&G[u][v]&&dy[v]==dx[u]+1){
vis[v]=1;
if(cy[v]!=-1&&dy[v]==dis){
continue;
}
if(cy[v]==-1||findpath(cy[v])){
cy[v]=u;cx[u]=v;
return 1;
}
}
}
return 0;
}
int Maxmatch()
{
int res=0;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
while(searchpath()){
memset(vis,0,sizeof(vis));
for(int i=1;i<=nx;i++){
if(cx[i]==-1){
res+=findpath(i);
}
}
}
return res;
}