P3386 【模板】二分图最大匹配
提交71.75k
通过27.33k
时间限制1.00s
内存限制512.00MB
提交答案加入题单
复制题目
题目提供者HOOCCOOH
难度普及+/提高
历史分数100
提交记录 查看题解
标签
O2优化
查看算法标签
进入讨论版
相关讨论
查看讨论
推荐题目
查看推荐
洛谷推荐关闭
展开
题目描述
给定一个二分图,其左部点的个数为 nn,右部点的个数为 mm,边数为 ee,求其最大匹配的边数。
左部点从 11 至 nn 编号,右部点从 11 至 mm 编号。
输入格式
输入的第一行是三个整数,分别代表 nn,mm 和 ee。
接下来 ee 行,每行两个整数 u, vu,v,表示存在一条连接左部点 uu 和右部点 vv 的边。
输出格式
输出一行一个整数,代表二分图最大匹配的边数。
输入输出样例
输入 #1复制
1 1 1 1 1
输出 #1复制
1
输入 #2复制
4 2 7 3 1 1 2 3 2 1 1 4 2 4 1 1 1
输出 #2复制
2
说明/提示
数据规模与约定
对于全部的测试点,保证:
- 1 \leq n, m \leq 5001≤n,m≤500。
- 1 \leq e \leq 5 \times 10^41≤e≤5×104。
- 1 \leq u \leq n1≤u≤n,1 \leq v \leq m1≤v≤m。
不保证给出的图没有重边。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
inline int read()
{
char ch=getchar();
int n=0,m=1;
while(ch<'0'||ch>'9')
{
if(ch=='-')m=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')n=(n<<3)+(n<<1)+ch-48,ch=getchar();
return n*m;
}
void write(int n)
{
if(n>9)write(n/10);
putchar(n%10+'0');
}
int n,m,p,d[N],head[N],to[N],ne[N],id,ans;
bool vis[N];
void add(int x,int y)
{
to[++id]=y,ne[id]=head[x],head[x]=id;
}
bool find(int u)
{
vis[u]=1;
for(int i=head[u];i;i=ne[i])
{
int v=to[i];
if(vis[d[v]])continue;
if(!d[v]||find(d[v]))
{
d[v]=u;
return true;
}
}
return false;
}
int main(int argc,char **argv)
{
n=read(),m=read(),p=read();
while(p--)
{
int x,y;
x=read(),y=read();
add(x,y);
}
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof vis);
if(find(i))ans++;
}
write(ans);
return 0;
}