二分图

 数据结构、算法总述:数据结构/算法 C/C++-CSDN博客


二分图节点由两个集合组成,且两个集合内部没有边的图。换言之,存在一种方案,将节点划分成满足以上性质的两个集合。

染色法

目的:验证给定的二分图是否可以进行二色染色

时间复杂度是 O(n+m)
int n;      // n表示点数
int h[N], e[M], ne[M], idx;     // 邻接表存储图
int color[N];       // 表示每个点的颜色,-1表示未染色,0表示白色,1表示黑色

// 参数:u表示当前节点,c表示当前点的颜色
bool dfs(int u, int c)
{
    color[u] = c;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (color[j] == -1)
        {
            if (!dfs(j, !c)) return false;
        }
        else if (color[j] == c) return false;
    }

    return true;
}

bool check()
{
    memset(color, -1, sizeof color);
    bool flag = true;
    for (int i = 1; i <= n; i ++ )
        if (color[i] == -1)
            if (!dfs(i, 0))
            {
                flag = false;
                break;
            }
    return flag;
}

题目:

860. 染色法判定二分图 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/problem/content/862/

匈牙利算法

我们可以看做一个月老在牵红线,现在左边是男生,右边是女生,互相都有心仪的对象,我们就要尽量每一个男生都好。然后就出现了一个图。

我们先看第一个男生,他有两个心仪的对象,先看第一个女生,还是单身,那就选第一个,然后看下一位,也是第一个单身,就她了。但是第三位男生就出问题了,他只有一位心仪的对象,但是呢,那位已经有对象了,但是这位男生还是不放弃,找到那个男朋友,说:“要不你换一换”。我们再一看,确实还有一个备胎单身,就换一个,这样两个人都好,最后一个也很正常,直接匹配。所以总结出十六字真言:待字闺中,据为己有;名花有主,求他放手。 所以说这也告诉我们不要轻易放弃,最后悔的不是做错,而是错过。

时间复杂度 O(n*m),实际运形时间远小于n*m
int n1, n2;     // n1表示第一个集合中的点数,n2表示第二个集合中的点数
int h[N], e[M], ne[M], idx;     // 邻接表存储所有边,匈牙利算法中只会用到从第一个集合指向第二个集合的边,所以这里只用存一个方向的边
int match[N];       // 存储第二个集合中的每个点当前匹配的第一个集合中的点是哪个
bool st[N];     // 表示第二个集合中的每个点是否已经被遍历过

bool find(int x)
{
    for (int i = h[x]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            st[j] = true;
            if (match[j] == 0 || find(match[j]))
            {
                match[j] = x;
                return true;
            }
        }
    }

    return false;
}

// 求最大匹配数,依次枚举第一个集合中的每个点能否匹配第二个集合中的点
int res = 0;
for (int i = 1; i <= n1; i ++ )
{
    memset(st, false, sizeof st);
    if (find(i)) res ++ ;
}

题目:

861. 二分图的最大匹配 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/problem/content/863/

  • 18
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

禊月初三

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

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

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

打赏作者

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

抵扣说明:

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

余额充值