求最小顶点覆盖,即求二分图最大匹配。可以一下消除一行或一列,属于行列匹配法。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510;
int n,k,cnt,map1[N][N],mat[N],vis[N];
inline int read(){
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
bool find(int x){
for(int i=1;i<=n;++i)
if(map1[x][i]&&!vis[i]){
vis[i]=1;
if(!mat[i]||find(mat[i])){mat[i]=x;return true;}
}
return false;
}
int main(){
n=read(),k=read();memset(map1,0,sizeof map1);
for(int i=1,x,y;i<=k;++i)x=read(),y=read(),map1[x][y]=1;
cnt=0;memset(mat,0,sizeof mat);
for(int i=1;i<=n;++i){
memset(vis,0,sizeof vis);
if(find(i))++cnt;
}
printf("%d",cnt);
return 0;
}