最大二分匹配问题——“相亲巧妙解匈牙利算法”

本文探讨了二分图的概念、判定方法,以及其在最大匹配问题中的应用,通过实例说明如何利用匈牙利算法解决男女相亲中的配对问题。同时,通过编程实例展示了如何在实际场景中使用匈牙利算法求解最小点覆盖,揭示了最大匹配和最小点覆盖之间的König定理。

二分图

1,什么是二分图

二分图又称作二部图,是图论中的一种特殊模型。
设G=(V, E)是一个无向图。如果顶点集 V可分割为两个互不相交的子集X和Y,并且图中每条边连接的两个顶点一个在 X中,另一个在 Y中,则称图G为二分图。
在这里插入图片描述

2,二分图相关性质

定理:当且仅当无向图G的每一个环
的结点数均是偶数时,图G才是一个二分图。如果无环,也视为二分图。

3,二分图的判定

如果一个图是连通的,可以用如下的染色法判定是否二分图:
我们把X部的结点颜色设为0,Y部的颜色设为1。
从某个未染色的结点u开始,做BFS或者DFS 。把u染为0,枚举u的儿子v。如果v未染色,就染为与u相反的颜色,如果已染色,则判断u与v的颜色是否相同,相同则不是二分图。
如果一个图不连通,则在每个连通块中作判定。如图所示
在这里插入图片描述

二分图的判定结合这道模板题看下:
给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环。

请你判断这个图是否是二分图。

输入格式
第一行包含两个整数 n 和 m。

接下来 m 行,每行包含两个整数 u 和 v,表示点 u 和点 v 之间存在一条边。

输出格式
如果给定图是二分图,则输出 Yes,否则输出 No。

数据范围
1≤n,m≤105
输入样例:
4 4
1 3
1 4
2 3
2 4
输出样例:
Yes
题目来源:染色法判断二分图
推荐 这道题的题中相关解释是根据我后面将的“男女相亲”来陈述的,可以先去看看男女相亲巧解匈牙利

#include<cstring>
#include<iostream>
using namespace std;
const int N = 100010, M = 200010;
int n, m;
int h[N], e[M], ne[M], idex;//因为邻接表存的是无向图,不仅要存ab也要存ba所以M的范围是N的两倍
int st[N];//判断点是否染色以及染的颜色是否相同
void add(int x, int y)
{
   
   
    //表示的是x->y的边
    e[idex] = y;
    ne[idex] = h[x];
    h[x] = idex++;

}
bool dfs(int u, int c)//表示将点u染成颜色c
{
   
   
    st[u] = c;
    for (int i = h[u]; i != -1; i = ne[i])
    {
   
   
        int j = e[i];
        if (!st[j])//如果未染色
        {
   
   
            if (!dfs(j, 3 - c))
                return false;
        }
        else if (st[j] == c) return false;//如果染色但是染色相同那么也是没用的


    }
    return true;




}
int main()
{
   
   

    cin >> n >> m;
    memset(h, -1, sizeof h);
    while (m--)
    {
   
   
        int u, v;
        cin >> u >> v;
        add(u, v
评论 24
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天少点debug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值