HDOJ 1068 Girls and Boys(二分图匹配 + 镜像构图)

一道关于二分图匹配的问题,要求找出最大独立集,即在给定的二分图中,两两之间没有缘分的人的最大集合。解决方法是构建包含原二分图及其镜像的图,并求其最大匹配数,最终得出最大独立集的大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


点击打开链接


题意:题目给出了n个男女,编号为0~n-1,其中有男生也有女生。然后给出n组关系,把每一个人和与他(她)有缘分的人输入。现在要挑几个人出来,他们两两之间都不能有缘分,那么最多可以挑几个人出来?


这道题如果是男生女生混合起来,左边是0~n-1,右边也是,这样构图明显是错的,因为如果左边的一个男生1匹配了右边的一个女生2,那么左边那个女生2本应该是不能再继续匹配的。我们希望的构图,是左边只有男生编号,右边是女生编号,左边1匹配右边2,但要是把编号分开来,是很难做到的。现在可以假设,男生有n个,编号为0~n-1,放在左边,女生也有n个,编号为0~n-1放在右边,左边的1匹配了右边的2,左边的2匹配了右边的1,这样就相当于我们希望得到的二分图再加上了一个镜像的该二分图。原图和镜像图的最大匹配数应该是一样的,两者的和是res,那么其中一个就是res/2。


最大独立集:从二分图顶点集中取出一个子顶点集,使他们两两之间不连通。

最大独立集顶点数 = 二分图中顶点数 - 最大匹配数



#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<vector>
#include<algorithm>
#define N 500
using namespace std;
int g[N][N], link[N], used[N];
int n, a, m, b, res;
int dfs(int u)
{
    for (int v = 0; v < n; v++)
        if (g[u][v] && !used[v])
        {
            used[v] = 1;
            if (link[v] == -1 || dfs(link[v]))
            {
                link[v] = u;
                return  1;
            }
        }
    return 0;
}
int main()
{
    while (~scanf("%d", &n))
    {
        memset(g, 0, sizeof(g));
        for (int i = 0; i < n; i++)
        {
            scanf("%d: (%d)", &a, &m);
            for (int j = 0; j < m; j++)
            {
                scanf("%d", &b);
                g[a][b] = 1;
            }
        }
        memset(link, -1, sizeof(link));
        res = 0;
        for (int i = 0; i < n; i++)
        {
            memset(used, 0, sizeof(used));
            if (dfs(i)) res++;
        }
        printf("%d\n", n - res/2);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值