将行与列构成二分图 重要点就是每次去除一个点,然后再找最大匹配 如果小于原来的最大匹配 说明该点为重要点
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
#define mod 100000007
typedef long long LL;
const int M = 310;
int mp[105][105];
int n,m,k;
int a[105],b[105];
int mat[105];
int vis[105];
int dfs(int v)
{
for(int i=1;i<=m;++i)
{
if(!vis[i]&&mp[v][i])
{
vis[i]=1;
if(mat[i]==-1||dfs(mat[i]))
{
mat[i]=v;
return 1;
}
}
}
return 0;
}
int dyd()
{
int res=0;
memset(mat,-1,sizeof(mat));
for(int i=1;i<=n;++i)
{
memset(vis,0,sizeof(vis));
res+=dfs(i);
}
return res;
}
int main()
{
int casee=1;
while(cin>>n>>m>>k)
{
memset(mp,0,sizeof(mp));
int t=1;
for(int i=1;i<=k;++i)
{
cin>>a[t]>>b[t];
mp[a[t]][b[t]]=1;
t++;
}
int ans=dyd();
int cnt=0;
for(int i=1;i<t;++i)
{
mp[a[i]][b[i]]=0;
int temp;
temp=dyd();
// cout<<temp<<endl;
if(temp<ans)
cnt++;
mp[a[i]][b[i]]=1;
}
printf("Board %d have %d important blanks for %d chessmen.\n",casee++,cnt,ans);
}
}