先来看看一道题目:二分图匹配
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入样例:
1 1 1
1 1
输出样例:
1
这道题很明显是一个二分图匹配
普通人: 废话标题就是这个,不是二分图匹配是什么
dalao: 这不网络流裸题吗,随随便便就过了
小蒟蒻(me) 不要在意那么多细节,模板就当模板做就可以了
好了不管这么多了,接下来进入正题
知道二分图的往下看
不知道的请移步这里二分图或什么是二分图(你不知道二分图来这儿干啥?请移步这儿)
首先介绍一下什么是二分图
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
来自百度百科,虽然看不,懂不过没关系,能看到这里说明你已经初步掌握了二分图
请过了下片这题再来看本博文
二分图染色
接下来把问题具体化一下
一直现在有n个男孩和m个女孩,两两组队参加舞会,已知第i个男孩和第j个互相有好感.现在要使得最多的人可以参加舞会
现在4个男孩,4个女孩,我们现在来由图片一个一个看
首先鸣人发现小樱没有人选,于是选了小樱去舞会
接下来二柱子来了,发现小樱尽然被选了,十分气愤,于是去看看谁选了小樱,结果发现是鸣人选了,于是愤怒全消了,凭借他们两个的基情,呸呸呸友情,这点小事算什么,反正我还有雏田,于是佐助选了小樱,鸣人选了雏田
然后李洛克来了,他也十分喜欢小樱,想和小樱去舞会,可是我们的二柱子还在那里啊,知道了这个消息之后十分气愤说:你又不是鸣人,况且我只有小樱了,给你了,我干什么去?于是李洛克十分伤心,但是突然发现天天还在,而前冇的人选,于是李洛克和天天组成了一对去舞会
突然路飞不知道从哪里跑到火影来了,看到了小樱,于是一见钟情,海贼王都不做了,就想和小樱一起去参加舞会,二柱子不干了,和路飞打了一场,路飞不敌灰溜溜的走了
现在已经有三个对匹配了,这明显是最大的匹配数量了,只剩下凤姐和路飞了,当路飞看到凤姐后,就大喊:我要回去,我是要当海贼王的男人(俺は海賊王になる男だ)
应该差不多理解吧
#include<bits/stdc++.h>
#define rg register
using namespace std;
typedef long long ll;
inline int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') f= (c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return f*x;
}
int n,m,e,u,v,cnt,head[10001],f[10001],bj[10001],ans;
struct node{
int to,next;
}a[2000001];
void add(int x,int y){
a[++cnt].to=y;
a[cnt].next=head[x];
head[x]=cnt;
}
int dfs(int u){
for(int i=head[u];i;i=a[i].next){
int v=a[i].to;
if(f[v])
continue;
f[v]=1;
if(!bj[v]||dfs(bj[v])){
bj[u]=v;
bj[v]=u;
return 1;
}
}
return 0;
}
int main(){
n=read(),m=read(),e=read();
for(int i=1;i<=e;i++){
u=read(),v=read();
if(v>m)
continue;
add(u,v+n);
add(v+n,u);
}
for(int i=1;i<=n;i++){
memset(f,0,sizeof(f));
if(dfs(i))
ans++;
}
printf("%d",ans);
}