二分图最大匹配【匈牙利 || Dinic最大流】

匈牙利算法

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);
    }

你可能感兴趣的:(网络流,二分图,最大流)