bzoj1066: [SCOI2007]蜥蜴
最大流,首先建模。 设每个石柱分为出节点和入节点。
1.设一个虚拟源点,与每个初始有蜥蜴的石柱连一条容量为1的边。
2.设一个虚拟汇点,与每个能跳出来的石柱连一条容量为INF的边。
3.每一对距离小于d的点,出节点和入节点连一条容量为INF的边。
4.每个点的入节点和出节点连一条容量为石柱高度的边。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 1000 + 10; const int maxm = 100000 + 10; const int INF = 0x3f3f3f3f; int n,m,d,S,T,vid=0,cnt=0,p=0; int h[maxn]; int id[25][25][2]; int to[maxm],next[maxm],f[maxm]; int dist[maxn],gap[maxn]; char tmp[25]; int abs(int x) { return (x > 0 ? x : -x); } void add(int u,int v,int F) { to[++p] = v; f[p] = F; next[p] = h[u]; h[u] = p; to[++p] = u; f[p] = 0; next[p] = h[v]; h[v] = p; } int ISAP(int u,int flow) { if(u == T) return flow; int cur = 0,aug,mindist = vid; for(int i = h[u]; ~i; i = next[i]) { if(f[i] && dist[to[i]]+1 == dist[u]) { aug = ISAP(to[i],min(f[i],flow-cur)); f[i] -= aug; f[i^1] += aug; cur += aug; if(cur == flow || dist[S] >= vid) return cur; } } if(cur == 0) { if(!--gap[dist[u]]) { dist[S] = vid; return cur; } for(int i = h[u]; ~i; i = next[i]) if(f[i]) mindist = min(mindist,dist[to[i]]); ++gap[dist[u]=mindist+1]; } return cur; } int flow() { int res = 0; gap[0] = vid; while(dist[S] < vid) res += ISAP(S,INF); return res; } void build() { memset(h,-1,sizeof(h)); p = -1; scanf("%d%d%d",&n,&m,&d); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { id[i][j][0] = ++vid; id[i][j][1] = ++vid; } S = ++vid; T = ++vid; for(int x1 = 1; x1 <= n; x1++) for(int y1 = 1; y1 <= m; y1++) { for(int x2 = 1; x2 <= n; x2++) for(int y2 = 1; y2 <= m; y2++) if(abs(x1-x2) + abs(y1-y2) <= d) if(x1 != x2 || y1 != y2) add(id[x1][y1][1],id[x2][y2][0],INF); if(x1 - d < 1 || x1 + d > n || y1 - d < 1 || y1 + d > m) add(id[x1][y1][1],T,INF); } for(int i = 1; i <= n; i++) { scanf("%s",tmp+1); for(int j = 1; j <= m; j++) add(id[i][j][0],id[i][j][1],tmp[j]-'0'); } for(int i = 1; i <= n; i++) { scanf("%s",tmp+1); for(int j = 1; j <= m; j++) if(tmp[j] == 'L') { add(S,id[i][j][0],1); cnt++; } } } void solve() { printf("%d\n",cnt - flow()); } int main() { build(); solve(); return 0; }