题意:这里有一片油田,但是不是纯净的,有的地方是水,现在有一个捞石油的机器,但是这个机器捞的范围是固定的,是2*1的一个矩形大小,那么对于整个油田打捞,也只能打捞2*1的地方,那么,最多可以打捞多少?
挨着的 '#' 就连边,然后求一次最大匹配,答案是最大匹配除以二(因为1 2和2 1这两对匹配实际效果是1,但是会算成2)
链接:hdu - 4185
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 605;
const int maxm = 1000;
struct Edge {
int to, next;
}edge[maxn * maxn];
int head[maxn * maxn], tol;
int link[maxn * maxn], vis[maxn * maxn];
void add(int a, int b) {
edge[tol].to = b;
edge[tol].next = head[a];
head[a] = tol++;
}
char bmap[maxn][maxn];
int mp[maxn][maxn];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int sum;
int dfs(int u) {
for(int i = head[u]; i != -1; i = edge[i].next) {
int v = edge[i].to;
if(!vis[v]) {
vis[v] = 1;
if(link[v] == -1 || dfs(link[v])) {
link[v] = u;
return 1;
}
}
}
return 0;
}
int maxmatch() {
int ans = 0;
memset(link, -1, sizeof(link));
for(int u = 1; u <= sum; u++) {
memset(vis, 0, sizeof(vis));
if(dfs(u)) {
ans++;
}
}
return ans;
}
int main()
{
int T, N;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++) {
tol = 0;
sum = 0;
memset(head, -1, sizeof(head));
scanf("%d", &N);
for(int i = 0; i < N; i++) {
scanf("%s", bmap[i]);
}
//建图
memset(mp, 0, sizeof(mp)) ;
for(int i = 0; i < N; i++) {
for(int j = 0; j < N; j++) {
if(bmap[i][j] == '#') {
mp[i][j] = ++sum;
}
}
}
for(int i = 0; i < N; i ++) {
for(int j = 0; j < N; j ++) {
if(bmap[i][j] == '#') {
for(int k = 0; k < 4; k ++) {
int x = i + dx[k], y = j + dy[k];
if(x < 0 || x >= N || y < 0 || y >= N) continue;
if(mp[x][y])
add(mp[i][j], mp[x][y]);
}
}
}
}
printf("Case %d: %d\n", cas, maxmatch() / 2);
}
return 0;
}