O(V^ 0.5 * m)
(对匈牙利的优化,比匈牙利算法略快)
原理:在增广匹配集合M时,每次同时寻找多条不相交的增广路径。
反正我没看懂是什么鬼,记下模板再说
int map[nx][ny];
int xlink[nx],ylink[ny]; // xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。
int dx[nx], dy[ny]; // dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号
int dis;
bool visit[ny]; //寻找增广路的标记数组
bool bfs(){
queue<int> q; // 存左集合的点
dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=1;i<=nx;i++)
if(xlink[i]==-1){
q.push(i); // 所有没被匹配的x入队
dx[i]=0;
}
while(!q.empty()){
int p=q.front();
q.pop();
if(dx[p]>dis)break;
for(int v=1;v<=ny;v++)
if(map[p][v]&&dy[v]==-1){
dy[v]=dx[p]+1;
if(ylink[v]==-1)
dis=dy[v];
else{
dx[ylink[v]]=dy[v]+1;
q.push(ylink[v]);
}
}
}
return dis!=INF;
}
bool dfs(int p){
for(int v=1;v<=ny;v++)
if(map[p][v]&&!vis[v]&&dy[v]==dx[p]+1){
vis[v]=true;
if(ylink[v]!=-1&&dy[v]==dis)continue;
if(ylink[v]==-1|| dfs(ylink[v])){
xlink[p]=v;
ylink[v]=p;
return true;
}
}
return false;
}
int Max_match(){
memset(xlink,-1,sizeof(xlink));
memset(ylink,-1,sizeof(ylink));
int ans=0;
while(bfs()){
memset(vis,false,sizeof(vis));
for(int i=1;i<=nx;i++)
if(xlink[i]==-1&&dfs(i))
ans++;
}
return ans;
}