匈牙利算法
int dfs(int u)
{
for(int i=head[u];i;i=E[i].nxt)
{
int v=E[i].v;
if(!vis[v]){
vis[v]=1;
if(!match[v]||dfs(match[v])){
match[v]=u; return 1;
}
}
}
return 0;
}
int solve()
{
int ans=0;
for(int i=1;i<=n;++i)//n是左部图结点个数
{
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
Dinic最大流
最大流的版本重点在于建图
建图后可套入任何一个最大流模板
求出的最大流即为最大匹配
首先源点向x部每个点连边,容量为1
保证x部每个点只被匹配一次
同理y部每个点向汇点连边,容量为1
保证y部每个点只被匹配一次
剩下原图的边直接连就好,注意节点编号问题
不会最大流的小伙伴可以看我的博客
图论算法-网络最大流【EK;Dinic】
建边过程:
int n,m,e;
//n,m分别为两个点集点数;e为原图中的边
cin>>n>>m>>e;
for(int i=1;i<=e;i++)
{
int u,v;
cin>>u>>v;
add(u,v+n,1);//先建原图的边,要注意节点编号以题目为准
add(v+n,u,0);
}
int s=0,t=n+m+1;//建立超级源点和超级汇点
for(int i=1;i<=n;i++)
{
add(0,i,1);
add(i,0,0);//将超级源点对X点集每个点引一条容量为1的边
}
for(int i=n+1;i<=n+m;i++)
{
add(i,t,1);//将Y点集每个点向超级汇点引一条容量为1的边
add(t,i,0);
}