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

9 篇文章 0 订阅
8 篇文章 0 订阅

匈牙利算法

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);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值