二分图的最大匹配(匈牙利算法)

11 篇文章 0 订阅
4 篇文章 0 订阅
看书看了好久,看不懂。
上网找代码研究,还是不懂。
突然瞄到书上的插图,顿悟,哈哈^_^
这里的代码修改了一些,贴上来。。


//  二分图的最大匹配(匈牙利算法)
#include  < cstdio >
#include 
< memory.h >
using   namespace  std;

const int XV = 100;
const int YV = 300;
int xv, yv;        // X , Y 点集的大小
int adj [XV] [YV];    // adj [i] [j] != 0 表示 xi 与 yj 邻接
bool sy [YV];        // 每轮中对于被搜过的点 yi , sy [i] = 1
int xm [XV];        // xm [i] 保存 xi 匹配的 Y 点
int ym [YV];        // ym [i] 保存 yi 匹配的 X 点


int path (int u)
{
    
//对于 X 中的点 u ,返回能否找到增广路(也即能否增大匹配数,递归,时间复杂度 O (xv * yv))
    for (int v = 0; v < yv; v ++)
        {
        
if (adj [u] [v] && !sy [v])
            { 
            sy [v] 
= true;
            
if (ym [v] == -1 || path (ym [v]) == 1)
                {
                xm [u] 
= v;
                ym [v] 
= u;
                
return 1;
                } 
            }
        }
    
return 0;   
}

int maxmatch ()
{
    
int cnt = 0;            // 匹配数
    memset (xm, -1sizeof (xm));    // xm [i] == -1 表示 xi 尚未匹配
    memset (ym, -1sizeof (ym));
    
for (int u = 0; u < xv; u ++)
        {
        
if (xm [u] == -1)
            {
            memset (sy, 
0sizeof (sy));
            cnt 
+= path (u);
            }
        }
    
return cnt;
}

int main()
{
    scanf (
"%d%d"&xv, &yv);    // 输入 X , Y 点集的大小

    
// 输入邻接矩阵,两种方式

    
int edge;
    scanf (
"%d"&edge);        // 输入边数
    memset (adj, 0sizeof (adj));    
    
for (int i = 0; i < edge; i ++)
        {
        
int u, v;
        scanf (
"%d%d"&u, &v);    // 输入关联的两点
        adj [u] [v] = 1;
        }
    
/*
    6 6 10
    0 0
    0 2
    1 3
    1 5
    2 1
    2 3
    3 4
    4 4
    4 5
    5 5
    6 6
    
*/
/*************************************************
    for (int i = 0; i < xv; i ++)
        {
        for (int j = 0; j < yv; j ++)
            {
            scanf ("%d", &adj [i] [j]);
            }
        }
*/
/*    
    1 0 1 0 0 0
    0 0 0 1 0 1
    0 1 0 0 0 1
    0 0 0 0 1 0
    0 0 0 0 1 1
    0 0 0 0 0 1
*************************************************
*/

    
int cnt = maxmatch ();        // 匹配

    
// 打印
    printf ("The maxmatch count is %d ", cnt);
    
for (int i = 0; i < xv; i ++)
        {
        printf (
"%d ", xm [i]);
        }
    
return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值