洛谷 P3386 【模板】二分图匹配
题目背景
二分图
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
输入样例#1:
1 1 1 1 1
输出样例#1:
1
说明
n,m<=1000,1<=u<=n,1<=v<=m
因为数据有坑,可能会遇到v>m的情况。请把v>m的数据自觉过滤掉。
算法:二分图匹配
++++++++++++++++++++++++++++++++++++++++++++++++++++
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #include<cstdlib> 8 #include<iomanip> 9 #include<cassert> 10 #include<climits> 11 #include<vector> 12 #include<list> 13 #include<map> 14 #define maxn 1000001 15 #define F(i,j,k) for(int i=j;i<=k;i++) 16 #define M(a,b) memset(a,b,sizeof(a)) 17 #define FF(i,j,k) for(int i=j;i>=k;i--) 18 #define inf 0x7fffffff 19 #define maxm 2016 20 #define mod 1000000007 21 //#define LOCAL 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int n1,n2,m; 30 int mp[maxm][maxm]; 31 int vis[maxn],link[maxn]; 32 inline bool find(int u) 33 { 34 F(i,1,n2){ 35 if(mp[u][i]&&!vis[i]){ 36 vis[i]=1; 37 if(link[i]==0||find(link[i])){ 38 link[i]=u; 39 return true; 40 } 41 } 42 } 43 return false; 44 } 45 int ans=0; 46 int main() 47 { 48 std::ios::sync_with_stdio(false);//cout<<setiosflags(ios::fixed)<<setprecision(1)<<y; 49 #ifdef LOCAL 50 freopen("data.in","r",stdin); 51 freopen("data.out","w",stdout); 52 #endif 53 cin>>n1>>n2>>m; 54 F(i,0,m-1){ 55 int x,y;cin>>x>>y; 56 mp[x][y]=1; 57 } 58 F(i,1,n1){ 59 M(vis,false); 60 if(find(i)) ans++; 61 } 62 cout<<ans<<endl; 63 return 0; 64 }