二分图匹配入门例题

本文介绍了二分图匹配的概念,包括最大匹配、增广路等关键要素,并通过四个实例阐述了如何利用二分图匹配解决实际问题,如罪犯关押、棋盘覆盖、车辆放置和导弹防御。同时提到了匈牙利算法在解决此类问题中的应用,以及带权最大匹配的KM算法。
摘要由CSDN通过智能技术生成

先上一些概念:

  1. “任意两条边都没有公共端点”的最大的边的集合称为二分图的最大匹配。
  2. 二分图的一组匹配S是最大匹配,当且仅当图中不存在S的增广路。
  3. 二分图匹配的要素有2,一是0要素,节点可以分成独立的两个集合,每个集合内部有0条边;1要素,每个节点只能与1条边匹配。
  4. 二分图最小点覆盖(选最少的点使得所有边都被覆盖)包含的点数==最大匹配包含的边数
  5. 二分图最大独立集(任意两点之间都没有边相连,包含的点数最多)==n-最大匹配数。

二分图最大匹配的板子,复杂度是(V*E)点数乘以边数:

const int maxn=409;
const int maxm=1e5+7;

struct Edge{
    int v,next;
}edge[maxm];

int head[maxn],top;
void init(){
    memset(head,-1,sizeof(head));
    top=0;
}

void add(int u,int v){
    edge[top].v=v;
    edge[top].next=head[u];
    head[u]=top++;
}

int match[maxn];
bool vis[maxn];

bool dfs(int u){
    int v;
    for(int i=head[u];i!=-1;i=edge[i].next){
        v=edge[i].v;
        if(!vis[v]){
            vis[v]=1;
            if(!match[v]||dfs(match[v])){
                match[v]=u;
                return 1;
            }
        }
    }
    return 0;
}
int main(){
    int res=0;//答案;
    for(int i=1;i<=n;++i){//一边的点;
        memset(vis,0,sizeof(vis));
        if(dfs(i)) ++res;
    }    

    return 0;
}

二分图匹配的模型有两个要素:

1、节点能分成独立的两个集合,每个集合内部有0条边。

2、每个节点只能与1条匹配边匹配。 

一、257. 关押罪犯

显然这个答案具有单调性,所以我们可以二分答案,然后比答案大的两个人显然不可以分到一起,所以我们建图,将两个人连边,然后跑一下无向图染色就行了,不用匈牙利。

#include<bits/stdc++.h>
using namespace std;

const int maxm=1e5+7;
const int maxn=2e4+7;

struct Node{
    int u,v,w;
}node[maxm];

struct Edge{
    int v,next;
}edge[maxm<<1];

int head[maxn],top;
void init(){
    memset(head,-1,sizeof(head));
    top=0;
}

void add(int u,int v){
    edge[top].v=v;
    edge[top].next=head[u];
    head[u]=top++;
}

int n,m;
bool color[maxn],vis[maxn];

bool dfs(int u,bool f){
    color[u]=f;
    vis[u]=1;
    int v;
    for(int i=head[u];i!=-1;i=edge[i].next){
        v=edge[i].v;
        if(!vis[v]){
            bool flag=dfs(v,!f);
            if(!flag) return 0;
        }
        else if(color[v]==color[u]) return 0;
    }
    return 1;
}

bool check(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值