題意:在一個網格中有若干個點,每一次可以一下子清除一行或者一列,問最少幾次可以將網格中的點全部清除。
通過每個點建立橫座標與縱座標的連接(即建邊),將橫座標和縱座標看做二分圖中的點,選擇最少的點來覆蓋所有的邊。
#include<algorithm>
#include<iostream>
//#include<stdio.h>
#include<vector>
#include<string>
#include<cstring>
#include<map>
using namespace std;
//#define int long long
const int manx=2e5+10;
const int manx2=1e7+10;
const int mod=1e9+7;
vector<int>vt[1010];
int gril[1010],used[1010];
int ffind(int x)
{
for(int i=0; i<(int)vt[x].size(); i++)
{
int y=vt[x][i];
if(!used[y])
{
used[y]=1;
if(gril[y]==-1||ffind(gril[y]))
{
gril[y]=x;
return 1;
}
}
}
return 0;
}
int main()
{
int n,k,x,y;
memset(gril,-1,sizeof gril);
cin>>n>>k;
while(k--)
{
cin>>x>>y;
vt[x].push_back(y+n);
vt[y+n].push_back(x);
}
int ans=0;
for(int i=1; i<=n*2; i++)
{
memset(used,0,sizeof used);
if(ffind(i))
ans++;
}
cout<<ans/2<<endl;
return 0;
}