对点有限制,考察拆点的技巧
当时犯了一个傻逼错误:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+15;
const int INF = 1e9;
const int mo = 998244353;
#define pb push_back
#define pii pair<int,int>
#define ft first
#define sd second
#define ffor(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define For(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define rfor(i,a,b,c) for(int i=(a);i>(b);i-=(c))
#define Rfor(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define all(x) (x).begin(), (x).end()
#define debug1(x) cerr<<"! "<<x<<endl;
#define debug2(x,y) cerr<<"# "<<x<<" "<<y<<endl;
int head[N], cnt;
int S, T;
struct edge
{
int to, nxt, w;
}e[N << 1];
void add(int u, int v, int w) {
e[cnt].to = v;
e[cnt].w = w;
e[cnt].nxt = head[u];
head[u] = cnt++;
}
int dep[N], cur[N];
bool bfs() {
memset(dep, -1, sizeof(dep));
queue<int> q;
q.push(S); dep[S] = 0;
cur[S] = head[S];
while (!q.empty()) {
int u = q.front(); q.pop();
for (int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].to;
if (dep[v] == -1 && e[i].w) {
dep[v] = dep[u] + 1;
cur[v] = head[v];
if (v == T) return true;
q.push(v);
}
}
}
return false;
}
int dfs(int u, int limit) {
if (u == T) return limit;
int flow = 0;
for (int i = cur[u]; ~i && flow < limit; i = e[i].nxt) {
cur[u] = i;
int v = e[i].to;
if (dep[v] == dep[u] + 1 && e[i].w) {
int mif = dfs(v, min(e[i].w, limit - flow));
e[i].w -= mif;
e[i ^ 1].w += mif;
flow += mif;
if (flow == limit) return flow;
}
}
return flow;
}
int dinic() {
int res = 0;
while (bfs()) {
res += dfs(S, INF);
}
return res;
}
void slv(){
memset(head, -1, sizeof(head));
int r, c, d; cin >> r >> c >> d;
vector<vector<int>> mp(r + 1, vector<int>(c + 1));
map<pii, pii> zb; int tot = 0; S = 0, T = 2 * r * c + 1;
auto cal = [&] (int x, int y) {
for (int i = x - d; i <= x + d; i++) {
for (int j = y - d; j <= y + d; j++) {
if (i == x && j == y) continue;
if (mp[x][y] == 0) continue;
if ((x - i) * (x - i) + (y - j) * (y - j) > d * d) continue;
int ru = zb[{x, y}].ft, ou = zb[{x, y}].sd;
if (i < 1 || j < 1) {
add(ou, T, INF);
add(T, ou, 0);
return;
}
if (i > r || j > c) {
add(ou, T, INF);
add(T, ou, 0);
return;
}
if (mp[i][j]) {
int ru1 = zb[{i, j}].ft, ou1 = zb[{i, j}].sd;
assert(ru1 && ou1);
add(ou, ru1, INF);
add(ru1, ou, 0);
// cout << x << ' ' << y << ' ' << i << ' ' << j << '\n';
}
}
}
};
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
char tmp; cin >> tmp;
mp[i][j] = tmp - '0';
if (mp[i][j]) {
if (zb[{i, j}].ft == 0) {
int ru = ++tot;
int ou = ++tot;
zb[{i, j}] = {ru, ou};
}
int ru = zb[{i, j}].ft, ou = zb[{i, j}].sd;
add(ru, ou, mp[i][j]);
add(ou, ru, 0);
}
}
}
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cal(i, j);
}
}
vector<vector<char>> mp2(r + 1, vector<char>(c + 1));
int ans = 0;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cin >> mp2[i][j];
if (mp2[i][j] == 'L') {
ans++;
if (zb[{i, j}].ft == 0) {
int ru = ++tot;
int ou = ++tot;
zb[{i, j}] = {ru, ou};
}
int ru = zb[{i, j}].ft;
add(S, ru, 1);
add(ru, S, 0);
}
}
}
// debug1(tot)
// cout << zb[{3, 3}].ft << " " << zb[{3, 3}].sd << endl;
cout << ans - dinic() << '\n';
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
slv();
}