二分图模板(洛谷P3386)
题目背景
二分图
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
说明
n,m≤1000,1≤u≤n,1≤v≤m
因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define maxn 5010 5 using namespace std; 6 inline int read() 7 { 8 int x=0,f=1; 9 char ch=getchar(); 10 while(ch<'0'||ch>'9') 11 { 12 if(ch=='-') f=-1; 13 ch=getchar(); 14 } 15 while(ch>='0'&&ch<='9') 16 { 17 x=x*10+ch-'0'; 18 ch=getchar(); 19 } 20 return x*f; 21 } 22 int ecnt,head[maxn],link[maxn],vis[maxn],n,m,e,ans; 23 struct edge 24 { 25 int u,v,next; 26 }E[maxn*maxn]; 27 void add(int u,int v) 28 { 29 E[++ecnt].u=u; 30 E[ecnt].v=v; 31 E[ecnt].next=head[u]; 32 head[u]=ecnt; 33 } 34 int dfs(int x) 35 { 36 for(int i=head[x];i;i=E[i].next) 37 { 38 int v=E[i].v; 39 if(!vis[v]) 40 { 41 vis[v]=1; 42 if(!link[v]||dfs(link[v])) 43 { 44 link[v]=x;return 1; 45 } 46 } 47 } 48 return 0; 49 } 50 int main() 51 { 52 n=read();m=read();e=read(); 53 for(int i=1;i<=e;++i) 54 { 55 int a=read(),b=read(); 56 if(a>n||b>m) continue; 57 add(a,b); 58 } 59 for(int i=1;i<=n;++i) 60 { 61 memset(vis,0,sizeof(vis)); 62 if(dfs(i)) ++ans; 63 } 64 printf("%d\n",ans); 65 return 0; 66 }