二分图匹配
一个图可以分成两个部分,其中同一部分的点没有边,不同部分有边相连,求解最多能匹配多少点。
采用匈牙利算法求解:
对于每个点的一种匹配
1.匹配点未选择,将此点与匹配点匹配。
2.匹配点已与其它点a匹配:将a进行匹配,即重复1,2步骤。
若满足以上条件之一,则此点可匹配。
#include<bits/stdc++.h>
using namespace std;
const int maxe=1000005;
const int maxn=2005;
int a,b,n,m,e,tot;
int las[maxe],nex[maxe];
int vis[maxn],lnk[maxn],matched[maxn];
int read()
{
int ch=0,x=0;while(ch=getchar(),ch<'0'||ch>'9');
while(x=x*10+ch-48,ch=getchar(),ch>='0'&&ch<='9');
return x;
}
void add(int x,int y){nex[++tot]=y;las[tot]=lnk[x];lnk[x]=tot;}
int find(int x)
{
for(int k=lnk[x];k;k=las[k])
{
if(vis[nex[k]])continue;
vis[nex[k]]=1;
if(!matched[nex[k]]){matched[nex[k]]=x;return 1;}
if(find(matched[nex[k]])){matched[nex[k]]=x;return 1;}
}
}
void maxcomplete()
{
int cnt=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(find(i))cnt++;
}
printf("%d",cnt);
}
int main()
{
n=read();m=read();e=read();
for(int i=1;i<=e;i++)
{
a=read();b=read();
if(b>m)continue;
add(a,b+n);
}
maxcomplete();
return 0;
}