二分图最大匹配
①Hopcroft-Carp算法
时间复杂度O(sqrt(n)*m)
struct edge
{
int v,nxt;
}e[M];
int n,m;
int head[N],e_cnt;
int mx[N],my[N],dx[N],dy[N],vis[N],dis;
queue<int> q;
void Init()
{
e_cnt=0;
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
}
void Addedge(int u,int v)
{
e[e_cnt].v=v;e[e_cnt].nxt=head[u];head[u]=e_cnt++;
}
bool SearchP()
{
while(!q.empty()) q.pop();
dis=inf;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=1;i<=n;i++)
{
if(mx[i]==-1)
{
q.push(i);
dx[i]=0;
}
}
while(!q.empty())
{
int u=q.front();q.pop();
if(dx[u]>dis) break;
for(int i=head[u];i!=-1;i=e[i].nxt)
{
int v=e[i].v;
if(dy[v]==-1)
{
dy[v]=dx[u]+1;
if(my[v]==-1) dis=dy[v];
else
{
dx[my[v]]=dy[v]+1;
q.push(my[v]);
}
}
}
}
return dis!=inf;
}
bool Dfs(int u)
{
for(int i=head[u];i!=-1;i=e[i].nxt)
{
int v=e[i].v;
if(!vis[v]&&dy[v]==dx[u]+1)
{
vis[v]=1;
if(my[v]!=-1&&dy[v]==dis) continue;
if(my[v]==-1||Dfs(my[v]))
{
my[v]=u;
mx[u]=v;
return true;
}
}
}
return false;
}
int Maxmatch()
{
int ans=0;
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));
while(SearchP())
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
if(mx[i]==-1&&Dfs(i)) ans++;
}
}
return ans;
}
②匈牙利算法
时间复杂度O(n*m)
struct edge
{
int v,nxt;
}e[M];
int n,m;
int head[N],e_cnt;
int vis[N],my[N],mx[N];
void Init()
{
e_cnt=0;
memset(head,-1,sizeof(head));
}
void Addedge(int u,int v)
{
e[e_cnt].v=v;e[e_cnt].nxt=head[u];head[u]=e_cnt++;
}
bool Dfs(int u)
{
for(int i=head[u];i!=-1;i=e[i].nxt)
{
int v=e[i].v;
if(!vis[v])
{
vis[v]=1;
if(my[v]==-1||Dfs(my[v]))
{
mx[u]=v;
my[v]=u;
return true;
}
}
}
return false;
}
int Maxmatch()
{
int ans=0;
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));
for(int i=1;i<=n;i++)
{
if(mx[i]==-1)
{
memset(vis,0,sizeof(vis));
if(Dfs(i)) ans++;
}
}
return ans;
}