[TJOI2013]循环格
费用流,
因为要求全部都是回路, 每个点出入度都为1,拆点分别代表出点和入点,剩下不多说。
注意边界可以走 即n->1
/**
* Problem:Grid
* Author:Shun Yao
* Time:2013.5.21
* Result:Accepted
* Memo:CostFlow
*/
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std;
const long dir[2][4] = {{0, 0, -1, 1}, {-1, 1, 0, 0}}, Maxt = 452;
long s, t, ans, p2[Maxt], q[Maxt], *l, *r;
long d[Maxt];
char inq[Maxt];
class gnode {
public:
long v, w;
char f;
gnode *op, *next;
gnode() {}
~gnode() {}
gnode(long V, long W, char F, gnode *o, gnode *ne):v(V), w(W), f(F), op(o), next(ne) {}
} *g[Maxt], *p1[Maxt];
void add(long x, long y, long w) {
g[x] = new gnode(y, w, 1, 0, g[x]);
g[y] = new gnode(x, -w, 0, g[x], g[y]);
g[x]->op = g[y];
}
char spfa() {
static long i;
static gnode *e;
memset(d, 0x7f, sizeof d);
d[s] = 0;
memset(inq, 0, sizeof inq);
inq[s] = 1;
l = q;
*l = s;
r = l + 1;
while (l != r) {
inq[*l] = 0;
if (d[*l] == 0x7f7f7f7f) {
++l;
if (l == q + Maxt)
l = q;
continue;
}
for (e = g[*l]; e; e = e->next)
if (e->f && d[e->v] > d[*l] + e->w) {
d[e->v] = d[*l] + e->w;
p1[e->v] = e;
p2[e->v] = *l;
if (!inq[e->v]) {
inq[e->v] = 1;
*r = e->v;
++r;
if (r == q + Maxt)
r = q;
}
}
++l;
if (l == q + Maxt)
l = q;
}
if (d[t] == 0x7f7f7f7f)
return 0;
ans += d[t];
for (i = t; i != s; i = p2[i]) {
p1[i]->f = !p1[i]->f;
p1[i]->op->f = !p1[i]->op->f;
}
return 1;
}
int main() {
static long n, m, i, j, k, x, y, z;
static char ch;
freopen("grid.in", "r", stdin);
freopen("grid.out", "w", stdout);
scanf("%ld%ld", &n, &m);
s = (n * m) << 1;
t = s + 1;
for (i = 0; i < n; ++i) {
for (j = 0; j < m; ++j) {
add(s, i * m + j, 0);
add(i * m + j + n * m, t, 0);
scanf(" %c", &ch);
switch (ch) {
case 'L':z = 0;break;
case 'R':z = 1;break;
case 'U':z = 2;break;
case 'D':z = 3;break;
}
for (k = 0; k < 4; ++k) {
x = (i + dir[0][k] + n) % n;
y = (j + dir[1][k] + m) % m;
add(i * m + j, x * m + y + n * m, k != z);
}
}
}
ans = 0;
while (spfa());
printf("%ld", ans);
fclose(stdin);
fclose(stdout);
return 0;
}
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号