码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )

时间:2015-12-11 14:55:01      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

结点容量..拆点然后随便写 

---------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
#define chk(x, y) (x >= 0 && x < R && y >= 0 && y < C)
 
const int maxn = 10000;
const int maxm = 2900;
 
int h[maxn], cnt[maxn];
int X[maxm][maxm], Y[maxm][maxm];
int R, C, D, V, S, T, N;
char s[maxm];
 
struct edge {
int to, cap;
edge *next, *rev;
} E[1000000], *pt = E, *head[maxn], *p[maxn], *cur[maxn];
 
inline void Add(int u, int v, int w) {
pt->to = v; pt->cap = w; pt->next = head[u]; head[u] = pt++;
}
 
inline void AddEdge(int u, int v, int w) {
Add(u, v, w); Add(v, u, 0);
head[u]->rev = head[v];
head[v]->rev = head[u];
}
 
void Init() {
V = N = 0;
scanf("%d%d%d", &R, &C, &D);
memset(X, -1, sizeof X);
for(int i = 0; i < R; i++) {
scanf("%s", s);
for(int j = 0; j < C; j++) if(s[j] > ‘0‘) {
X[i][j] = V++;
Y[i][j] = V++;
AddEdge(X[i][j], Y[i][j], s[j] - ‘0‘);
}
}
S = V++; T = V++;
for(int i = 0; i < R; i++)
for(int j = 0; j < C; j++) if(~X[i][j])
for(int d = 1; d <= D; d++)
for(int k = 0; k <= d; k++) {
int x = i + k, y = j + d - k;
if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
x = i - k, y = j - d + k;
if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
x = i + k, y = j - d + k;
if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
x = i - k, y = j + d - k;
if(chk(x, y) && ~X[x][y]) AddEdge(Y[i][j], X[x][y], maxn);
}
for(int i = 0; i < R; i++) {
scanf("%s", s);
for(int j = 0; j < C; j++) {
if(~X[i][j] && (i < D || j < D || i + D >= R || j + D >= C)) AddEdge(Y[i][j], T, maxn);
if(s[j] != ‘.‘) AddEdge(S, X[i][j], 1), N++;
}
}
}
 
void Solve() {
memset(cnt, 0, sizeof cnt);
memset(h, 0, sizeof h);
cnt[0] = V;
for(int i = 0; i < V; i++) cur[i] = head[i];
int Flow = 0; edge* e;
for(int x = S, A = maxn; h[S] < V; ) {
for(e = cur[x]; e; e = e->next)
if(h[e->to] + 1 == h[x] && e->cap) break;
if(e) {
p[e->to] = cur[x] = e;
A = min(A, e->cap);
if((x = e->to) == T) {
for(; x != S; x = p[x]->rev->to) {
p[x]->cap -= A;
p[x]->rev->cap += A;
}
Flow += A;
A = maxn;
}
} else {
if(!--cnt[h[x]]) break;
h[x] = V;
for(e = head[x]; e; e = e->next) if(h[e->to] + 1 < h[x] && e->cap) {
h[x] = h[e->to] + 1;
cur[x] = e;
}
cnt[h[x]]++;
if(x != S) x = p[x]->rev->to;
}
}
printf("%d\n", N - Flow);
}
 
int main() {
Init();
Solve();
return 0;
}

---------------------------------------------------------------

 

BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )

标签:

原文地址:http://www.cnblogs.com/JSZX11556/p/5038712.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!