中文题,题目不用多说,先求出最大匹配,然后依次把每条边剪短,再取最大匹配,如果比最初的匹配值小,num++
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int maxn=111;
int map[maxn][maxn];
int link[maxn];
int visit[maxn];
int n,m,p;
bool dfs(int k)
{
for(int i=1;i<=m;i++)
{
if(!visit[i]&&map[k][i])
{
visit[i]=1;
int j=link[i];
if(j==-1||dfs(j))
{
link[i]=k;
return true;
}
}
}
return false;
}
int hungary()
{
int num=0;
memset(link,-1,sizeof(link));//初始化
for(int i=1;i<=n;i++)
{
memset(visit,0,sizeof(visit));
if(dfs(i))//有增广路
{
num++;//匹配数++
}
}
return num;
}
int main()
{
int x,y;
int ans;
int t=1;
int num;
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
memset(map,0,sizeof(map));
for(int i=0;i<p;i++)
{
scanf("%d %d",&x,&y);
map[x][y]=1;
}
ans=hungary();
//cout<<ans<<endl;
num=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(map[i][j]==1)
{
map[i][j]=0;
if(hungary()<ans)
{
num++;
}
map[i][j]=1;
}
}
}
printf("Board %d have %d important blanks for %d chessmen.\n",t++,num,ans);
}
return 0;
}