题面
思路
有蜥蜴连超级源点,可以出图的连超级汇点,不用说了,然后就是有高度的柱子裂点,边权为高度,然后可以互相跳的连边,跑dinic就好了。
代码实现
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define MT(x,i) memset(x,i,sizeof(x) )
#define rev(i,start,end) for (int i=start;i<end;i++)
#define inf 0x3f3f3f3f
#define mp(x,y) make_pair(x,y)
#define lowbit(x) (x&-x)
#define exp 1e-8
#define N 1000005
#define fi first
#define se second
#define pb push_back
const int mod=1e9+7;
typedef long long ll;
typedef vector <int> VI;
typedef pair<int ,int> PII;
typedef pair<int ,PII> PIII;
ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
inline int read() {
char ch=getchar(); int x=0, f=1;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
} while('0'<=ch&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
} return x*f;
}
const int maxn=1e4+10;
struct edge {
int v,flow,next;
}e[500000];
int head[maxn],cnt=-1;
inline void add (int u,int v,int flow) {
e[++cnt]=(edge) {v,flow,head[u]};
head[u]=cnt;
}
inline void add_edge (int u,int v,int flow) {
add (u,v,flow);
add (v,u,0);
}
int dis[maxn],cur[maxn];
int s,t,n,m,ans,x,y;
int bfs () {
MT (dis,0);
queue<int > q;
q.push (s);
dis[s]=1;
while (q.size ()) {
int x=q.front (); q.pop ();
for (int i=head[x];i!=-1;i=e[i].next) {
if (dis[e[i].v]==0&&e[i].flow) {
dis[e[i].v]=dis[x]+1;
q.push (e[i].v);
}
}
}
return dis[t];
}
int dfs (int now,int nowflow) {
if (now==t) return nowflow;
for (int &i=cur[now];~i;i=e[i].next) {
if (dis[e[i].v]==dis[now]+1&&e[i].flow) {
int canflow=dfs (e[i].v,min (nowflow,e[i].flow));
if (canflow>0) {
e[i].flow-=canflow;
e[i^1].flow+=canflow;
return canflow;
}
}
}
return 0;
}
void Dinic () {
while (bfs ()) {
for (int i=s;i<=t;i++) cur[i]=head[i];
while (int val=dfs(s,inf)) ans+=val;
}
}
inline int id1 (int x,int y) {
return (x-1)*m+y;
}
inline int id2 (int x,int y) {
return (x-1)*m+y+n*m;
}
inline int distance (int x1,int y1,int x2,int y2) {
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
int st,k,allcost;
int height[maxn][maxn];
char s1[210];
char s2[210];
int main () {
scanf ("%d%d%d",&n,&m,&st);
MT (head,-1);
s=0,t=n*m*2+1;
rep (i,1,n) {
scanf ("%s",s1+1);
rep (j,1,m) if (s1[j]-'0'>0) add_edge (id1 (i,j),id2 (i,j),s1[j]-'0');
}
rep (i,1,n) {
scanf ("%s",s2+1);
rep (j,1,m) if (s2[j]=='L') {
add_edge (s,id1 (i,j),1),allcost++;
}
}
rep (i,1,n)
rep (j,1,m) {
if (i-st<1||i+st>n||j-st<1||j+st>m) {
add_edge (id2 (i,j),t,inf);
}
}
rep (x1,1,n)
rep (y1,1,m)
rep (x2,1,n)
rep (y2,1,m) {
if (distance (x1,y1,x2,y2)<=st*st) {
add_edge (id2 (x1,y1),id1 (x2,y2),inf);
}
}
Dinic ();
printf ("%d
",allcost-ans);
return 0;
}