中文题面
注意建图方式:
- 将行与列看作顶点
- 棋子所在的位置的行与列所对应的顶点建边
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int N,M,K;
bool G[105][105];
int V;
int match[205];
bool used[205];
int col[10010],row[10010];
bool dfs(int u){
for (int i = 1;i <=N;i++){
if (!used[i] && G[u][i]){
used[i] = true;
if (match[i] < 0 || dfs(match[i])){
match[i] = u;
return true;
}
}
}
return false;
}
int bipartitie_matching(){
int res = 0;
memset(match,-1,sizeof match);
for (int v = 1;v<=N;v++){
memset(used,0,sizeof used);
if (dfs(v)) res++;
}
return res;
}
int main()
{
int t = 0;
while(scanf("%d%d%d",&N,&M,&K) != EOF){
memset(G,0,sizeof G);
for (int i = 0;i<K;i++){
int x,y;
scanf("%d%d",&col[i],&row[i]);
G[col[i]][row[i]] = true;
}
int max_match = bipartitie_matching();
int l = 0,ans;
for (int i = 0;i<K;i++){
G[col[i]][row[i]] = false;
ans = bipartitie_matching();
if (ans < max_match) l++;
G[col[i]][row[i]] = true;
}
printf("Board %d have %d important blanks for %d chessmen.\n",++t,l,max_match) ;
}
return 0;
}