• 匈牙利算法 -- Acwing 861. 二分图的最大匹配


    Acwing 861. 二分图的最大匹配

    题目描述

    给定一个二分图,其中左半部包含 n1 个点(编号 1∼n1),右半部包含 n2 个点(编号 1∼n2),二分图共包含 m条边。

    数据保证任意一条边的两个端点都不可能在同一部分中。

    请你求出二分图的最大匹配数。

    二分图的匹配:给定一个二分图 G,在 G 的一个子图 M 中,M 的边集 {E} 中的任意两条边都不依附于同一个顶点,则称 M是一个匹配。
    二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。

    输入格式

    第一行包含三个整数 n1、 n2 和 m。

    接下来 m
    行,每行包含两个整数 u 和 v,表示左半部点集中的点 u 和右半部点集中的点 v 之间存在一条边。

    输出格式

    输出一个整数,表示二分图的最大匹配数。
    
    • 1

    数据范围

    1≤n1,n2≤500,
    1≤u≤n1,
    1≤v≤n2,
    1≤m≤105

    思路

    用左边的点去匹配右边,如果右边的节点右匹配点。则尝试将右边节点匹配的节点重新匹配。如果成功那么该节点就匹配成功。

    代码

    #include
    #include
    #include
    using namespace std;
    
    const int N = 510, M = 200010;
    
    int e[M],ne[M],h[N],idx;
    
    int n , m,n1,n2;
    int match[N];  // 记录每个右边节点,匹配的是哪一个节点。
    bool st[N];  //右边每个点的状态,遍历左边节点的时候的记录下匹配过哪些节点。
    void add(int a, int b)
    {
        e[idx] = b ,ne[idx] = h[a] ,h[a ] = idx ++ ;
    }
    
    bool find(int u)
    {
        for(int i = h[u]; i != -1; i = ne[i])
        {
            
            int j = e[i];
            if(!st[j])  // 还没有匹配过
            {
                st[j] = true;
                if(match[j] == 0 || find(match[j])) // 没有对应匹配的左节点 或者可以j节点的匹配节点可以重新匹配成功
                {
                    match[j] = u; return true;
                }
            }
        }
        
        return false ;
    }
    int main()
    {
        cin>>n1>>n2>>m;
        
        memset(h,-1,sizeof h);
        while(m--)
        {
            int u,v;
            cin>>u>>v;
            add(u,v);
        }
        int res = 0;
        for(int i = 1 ; i <= n1 ; ++ i)
        {
            memset(st,false,sizeof st); // 表示还没开始匹配任意一个节点 防止重复匹配。
            if(find(i)) res ++ ;
        }
        cout<<res;
        return 0;
        
    }
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    止重复匹配。
    if(find(i)) res ++ ;
    }
    cout< return 0;

    }

    • 相关阅读:
      集合java
      Ansible初识以及安装
      linux如何创建文件
      cube-studio 部署过程
      蓝桥杯每日一题0223.10.23
      Vue2 基础一指令
      竞赛选题 深度学习动物识别 - 卷积神经网络 机器视觉 图像识别
      学习ASP.NET Core Blazor编程系列四——迁移
      激光雷达市场格局“剧变”,这家国产厂商成了最大黑马?
      NSS [UUCTF 2022 新生赛]websign
    • 原文地址:https://blog.csdn.net/m0_66600340/article/details/126145713