首先。。。这是道(很水的)网络流
我们发现"每个时刻不能有两个蜥蜴在同一个柱子上"这个条件是没有用的因为可以让外面的先跳,再让里面的往外跳
但是还有柱子高度的限制,于是把柱子拆点为p1和p2,p1向p2连边,边权为柱子高度
对于相距(注意!是欧几里得距离!)小于d的两个柱子p和q,q2向p1连边,p2向q1连边,边权为inf
S向有蜥蜴的柱子的p1连边,边权为1,可以一步跳出去的柱子p2向T连边,边权为inf
跑最大流即可
1 /************************************************************** 2 Problem: 1066 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:136 ms 7 Memory:12656 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 14 using namespace std; 15 const int N = 1e3 + 5; 16 const int M = N * N; 17 const int inf = 1e9; 18 19 struct edge { 20 int next, to, f; 21 edge(int _n = 0, int _t = 0, int _f = 0) : next(_n), to(_t), f(_f) {} 22 } e[M]; 23 24 int n, m, D, cnt_p, S, T, ans; 25 int first[N], tot = 1; 26 int w[25][25]; 27 int d[N], q[N]; 28 29 inline void Add_Edges(int x, int y, int f) { 30 e[++tot] = edge(first[x], y, f), first[x] = tot; 31 e[++tot] = edge(first[y], x, 0), first[y] = tot; 32 } 33 34 #define y e[x].to 35 #define p q[l] 36 bool bfs() { 37 static int l, r, x; 38 memset(d, -1, sizeof(d)); 39 d[q[1] = S] = 1; 40 for (l = r = 1; l != r + 1; ++l) 41 for (x = first[p]; x; x = e[x].next) 42 if (!~d[y] && e[x].f) { 43 d[q[++r] = y] = d[p] + 1; 44 if (y == T) return 1; 45 } 46 return 0; 47 } 48 #undef p 49 50 int dfs(int p, int lim) { 51 if (p == T || !lim) return lim; 52 int x, tmp, rest = lim; 53 for (x = first[p]; x && rest; x = e[x].next) 54 if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) { 55 rest -= (tmp = dfs(y, tmp)); 56 e[x].f -= tmp, e[x ^ 1].f += tmp; 57 if (!rest) return lim; 58 } 59 if (rest) d[p] = -1; 60 return lim - rest; 61 } 62 #undef y 63 64 inline int Dinic() { 65 int res = 0; 66 while (bfs()) 67 res += dfs(S, inf); 68 return res; 69 } 70 71 template <class T> T sqr(T x) { 72 return x * x; 73 } 74 75 #define in(x, y) w[x][y] * 2 - 1 76 #define out(x, y) w[x][y] * 2 77 int main() { 78 int i, j, k, l; 79 char ch; 80 scanf("%d%d%d", &n, &m, &D); 81 for (cnt_p = 0, i = 1; i <= n; ++i) 82 for (j = 1; j <= m; ++j) { 83 ch = getchar(); 84 while (ch < '0' || ch > '3') ch = getchar(); 85 w[i][j] = ++cnt_p; 86 if (ch != '0') Add_Edges(in(i, j), out(i, j), ch - '0'); 87 } 88 S = cnt_p * 2 + 1, T = S + 1; 89 for (i = 1; i <= n; ++i) 90 for (j = 1; j <= m; ++j) 91 for (k = 1; k <= n; ++k) 92 for (l = 1; l <= m; ++l) 93 if (sqr(i - k) + sqr(j - l) <= D * D && ((i != k) || (j != l))) 94 Add_Edges(out(i, j), in(k, l), inf); 95 for (i = 1; i <= n; ++i) 96 for (j = 1; j <= m; ++j) { 97 ch = getchar(); 98 while (ch != '.' && ch != 'L') ch = getchar(); 99 if (ch == 'L') ++ans, Add_Edges(S, in(i, j), 1); 100 if (i <= D || j <= D || i > n - D || j > m - D) 101 Add_Edges(out(i, j), T, inf); 102 } 103 printf("%d\n", ans - Dinic()); 104 return 0; 105 } 106 #undef in 107 #undef out
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen