题解:将所有的横坐标看作一边的点,纵坐标看作另一边的点,然后二分图匹配即可,建图很巧妙……
#include <cstdio>
#include <cstring>
#define maxn 105
bool map[maxn][maxn],vis[maxn];
int n,m,k,mark[maxn],edge[maxn*maxn][2];
bool dfs(int v){
for(int i=1;i<=m;i++){
if(vis[i]||!map[i][v])
continue;
vis[i]=true;
if(mark[i]==0||dfs(mark[i])){
mark[i]=v;
return true;
}
}
return false;
}
int Hungarian(){
int count=0;
memset(mark,0,sizeof(mark));
for(int i=1; i<=n; i++){
memset(vis,false,sizeof(vis));
if(dfs(i)) count++;
}
return count;
}
int main(){
int i,sum,num=1;
while(scanf("%d%d%d",&n,&m,&k)!=EOF){
memset(map,false,sizeof(map));
for(i=0;i<k;i++){
scanf("%d%d",&edge[i][0],&edge[i][1]);
map[edge[i][0]][edge[i][1]] = true;
}
int max=Hungarian();
for(i=sum=0;i<k;i++){
map[edge[i][0]][edge[i][1]]=false;
if(max>Hungarian()) sum++;
map[edge[i][0]][edge[i][1]]=true;
}
printf("Board %d have %d important blanks for %d chessmen.\n",num++,sum,max);
}
return 0;
}