http://acm.hdu.edu.cn/showproblem.php?pid=1281
题意为nxm的地图上给出k个车,问图中能存在的最多马个数(不能同行同列),且其中的格子(若不放置车,则会导致能放置的车个数减少)的个数。
求出行列最大匹配, 枚举每个可放置车的格子,若取消该格子会导致最大匹配数减少,则计数+1
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100 + 5;
bool path[maxn][maxn];
int link[maxn], vis[maxn];
bool dfs(int u, int m) {
for(int v = 1; v <= m; ++v) {
if(!vis[v] && path[u][v]) {
vis[v] = 1;
if(link[v] == -1 || dfs(link[v], m)) {
link[v] = u;
return true;
}
}
}
return false;
}
int max_match(int n, int m) {
int res = 0;
memset(link, -1, sizeof(link));
for(int i = 1; i <= n; ++i) {
memset(vis, 0, sizeof(vis));
if(dfs(i, m)) res++;
}
return res;
}
pair<int, int> arr[maxn * maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, K, cas = 1;
while(cin >> n >> m >> K) {
int x, y;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
path[i][j] = false;
for(int i = 0; i < K; ++i) {
cin >> arr[i].first >> arr[i].second;
path[arr[i].first][arr[i].second] = true;
}
int ans = max_match(n, m), cnt = 0;
for(int i = 0; i < K; ++i) {
path[arr[i].first][arr[i].second] = false;
if(max_match(n, m) < ans) cnt++;
path[arr[i].first][arr[i].second] = true;
}
cout << "Board " << cas++ << " have " << cnt << " important blanks for " << ans << " chessmen." << endl;
}
}