在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。
输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。
输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<vector> #include<map> using namespace std; const int maxn = 25; const int INF = 1E9; struct E{ int flow,cap,from,to; E(){} E(int flow,int cap,int from,int to) : flow(flow),cap(cap),from(from),to(to) {} }edgs[maxn*maxn*maxn*maxn*4]; int d,n,m,tot = 0,h[maxn][maxn],cur = 0,L[maxn*maxn*2+10],cnt[maxn*maxn*2+10]; int fa[maxn*maxn*2+10],a[maxn*maxn*2+10]; char p[maxn]; bool vis[maxn*maxn*2+10]; vector <int> G[maxn*maxn*2+10]; queue <int> q; int num(int x,int y) {return m*(x-1)+y;} void Add(int Num,int cap,int from,int to) { G[from].push_back(Num); edgs[Num] = E(0,cap,from,to); } int dis(int A,int B,int C,int D) { int X = (A-C)*(A-C); int Y = (B-D)*(B-D); return X+Y; } bool BFS() { memset(vis,0,sizeof(vis)); memset(L,0,sizeof(L)); vis[0] = 1; L[0] = 1; q.push(0); while (!q.empty()) { int k = q.front(); q.pop(); for (int l = 0; l < G[k].size(); l++) { E e = edgs[G[k][l]]; if (vis[e.to] || e.cap - e.flow <= 0) continue; vis[e.to] = 1; L[e.to] = L[k] + 1; q.push(e.to); } } return vis[n*m*2+1]; } int DFS(int k,int a) { if (a <= 0 || k == n*m*2+1) return a; int f,flow = 0; for (int &i = cnt[k]; i < G[k].size(); i++) { E &e = edgs[G[k][i]]; if (L[e.to] == L[k]+1 && (f = DFS(e.to,min(e.cap - e.flow,a))) > 0) { flow += f; e.flow += f; a -= f; edgs[G[k][i]^1].flow -= f; if (a == 0) break; } } return flow; } void solve() { int x = n*m*2+1; while (x != 0) { edgs[fa[x]].flow += a[n*m*2+1]; edgs[fa[x]^1].flow -= a[n*m*2+1]; x = edgs[fa[x]].from; } } int main() { #ifdef YZY freopen("yzy.txt","r",stdin); #endif cin >> n >> m >> d; for (int i = 1; i <= n; i++) { scanf("%s",1+p); for (int j = 1; j <= m; j++) h[i][j] = p[j] - '0'; } for (int i = 1; i <= n; i++) { scanf("%s",1+p); for (int j = 1; j <= m; j++) if (p[j] == 'L') { ++tot; Add(cur++,1,0,num(i,j)); Add(cur++,0,num(i,j),0); } } for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (h[i][j]) { int N = num(i,j); Add(cur++,h[i][j],N,N+n*m); Add(cur++,0,N+n*m,N); if (i + d > n || i - d < 1 || j + d > m || j - d < 1) { Add(cur++,INF,N+n*m,n*m*2+1); Add(cur++,0,n*m*2+1,N+n*m); } for (int i1 = 1; i1 <= n; i1++) for (int j1 = 1; j1 <= m; j1++) if ((i != i1 || j != j1) && dis(i,j,i1,j1) <= d*d) { if (h[i1][j1]) { int T = num(i1,j1); Add(cur++,INF,N+n*m,T); Add(cur++,0,T,N+n*m); } } } int flow = 0; while (BFS()) { memset(cnt,0,sizeof(cnt)); flow += DFS(0,INF); } /* for (;;) { memset(vis,0,sizeof(vis)); vis[0] = 1; q.push(0); bool flag = 0; a[0] = INF; while (!q.empty()) { int k = q.front(); q.pop(); for (int l = 0; l < G[k].size(); l++) { E e = edgs[G[k][l]]; if (vis[e.to] || e.cap - e.flow <= 0) continue; vis[e.to] = 1; fa[e.to] = G[k][l]; a[e.to] = min(a[k],e.cap - e.flow); q.push(e.to); } if (vis[n*m*2+1]) { flow += a[n*m*2+1]; solve(); flag = 1; while (!q.empty()) q.pop(); break; } } if (!flag) break; } */ cout << tot - flow; return 0; }