BZOJ1066: [SCOI2007]蜥蜴

1066: [SCOI2007]蜥蜴

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4506  Solved: 2305
[Submit][Status][Discuss]

Description

  在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
石柱上。

Input

  输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

Output

  输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

Sample Input

5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........

Sample Output

1

HINT

100%的数据满足:1<=r, c<=20, 1<=d<=4

Source

 

【题解】

此题每个点有流量限制,可以考虑拆点。

点x拆成x和x'。

有蜥蜴的点x,从S连向x,容量为1

能跳到外部的点x,从x'连向T,容量为INF

能彼此到达的点x,y,从x'连向y,从y'连向x,容量为INF,这样从x走向y,必须先从x走向x'再走向y,限制了点x的流量

然后从x连向x',容量为点x的流量限制

 

挂了好多细节

写题要专心,一不专心就挂细节

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <cmath>
  7 #include <queue>
  8 #include <vector>
  9 #define min(a, b) ((a) < (b) ? (a) : (b))
 10 #define max(a, b) ((a) > (b) ? (a) : (b))
 11 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 12 inline void swap(int &a, int &b)
 13 {
 14     long long tmp = a;a = b;b = tmp;
 15 }
 16 inline void read(int &x)
 17 {
 18     x = 0;char ch = getchar(), c = ch;
 19     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 20     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 21     if(c == '-')x = -x;
 22 }
 23 
 24 const int INF = 0x3f3f3f3f;
 25 const int MAXN = 500;
 26 const int MAXM = 2000000;
 27 
 28 struct Edge
 29 {
 30     int u,v,w,nxt;
 31     Edge(int _u, int _v, int _w, int _nxt){u = _u;v = _v;w = _w;nxt = _nxt;}
 32     Edge(){}
 33 }edge[MAXM << 1];
 34 int head[200000], cnt = 1, q[200000], h[200000], ans = 0, S, T;
 35 
 36 inline void insert(int a, int b, int c)
 37 {
 38     edge[++cnt] = Edge(a,b,c,head[a]);
 39     head[a] = cnt;
 40     edge[++cnt] = Edge(b,a,0,head[b]);
 41     head[b] = cnt;
 42 }
 43 
 44 bool bfs()
 45 {
 46     int he = 0, ta = 1;
 47     memset(h, -1, sizeof(h));
 48     q[he] = S, h[S] = 0;
 49     while(he < ta)
 50     {
 51         int now = q[he ++];
 52         for(int pos = head[now];pos;pos = edge[pos].nxt)
 53         {
 54             int v = edge[pos].v;
 55             if(h[v] == -1 && edge[pos].w)
 56             {
 57                 h[v] = h[now] + 1;
 58                 q[ta ++] = v;
 59             }
 60         }
 61     }
 62     return h[T] != -1;
 63 }
 64 
 65 int dfs(int x, int f)
 66 {
 67     if(x == T) return f;
 68     int w, used = 0;
 69     for(int pos = head[x];pos;pos = edge[pos].nxt)
 70     {
 71         int v = edge[pos].v;
 72         if(h[v] == h[x] + 1)
 73         {
 74             w = dfs(v, min(f - used, edge[pos].w));
 75             edge[pos].w -= w;
 76             edge[pos ^ 1].w += w;
 77             used += w;
 78             if(used == f) return f;
 79         }
 80     }
 81     if(!used) h[x] = -1;
 82     return used;
 83 }
 84 
 85 void dinic()
 86 {
 87     while(bfs()) ans += dfs(S, INF);
 88 }
 89 
 90 int r,c,d,g[MAXN][MAXN],x[MAXN << 1],y[MAXN << 1],w[MAXN << 1],tot,t;
 91 char s[MAXN][MAXN];
 92 
 93 int main()
 94 {
 95     S = 100000, T = 100001;
 96     read(r), read(c), read(d);
 97     for(register int i = 1;i <= r;++ i)
 98     {
 99         scanf("%s", s[i] + 1);
100         for(register int j = 1;j <= c;++ j)
101             g[i][j] = s[i][j] - '0';
102     }
103     for(register int i = 1;i <= r;++ i)
104         scanf("%s", s[i] + 1);
105     for(register int i = 1;i <= r;++ i)
106         for(register int j = 1;j <= c;++ j)
107         {
108             if(s[i][j] == 'L') ++ t;
109             if(g[i][j] > 0)
110             {
111                 ++ tot;x[tot] = i, y[tot] = j, w[tot] = g[i][j];
112             }
113         } 
114     for(register int i = 1;i <= tot;++ i)
115     {
116         int tmp = min(x[i], min(y[i], min(r - x[i] + 1, c - y[i] + 1)));
117         if(tmp <= d) 
118             insert(i + tot, T, INF);
119         if(s[x[i]][y[i]] == 'L') 
120             insert(S, i, 1);
121         insert(i, i + tot, w[i]);
122     }
123     for(register int i = 1;i <= tot;++ i)
124         for(register int j = i + 1;j <= tot;++ j)
125         {
126             if((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) <= d * d)
127                 insert(i + tot, j, INF), insert(j + tot, i, INF);
128         }
129     dinic();
130     printf("%d", t - ans);
131     return 0;
132 }
BZOJ1066

 

posted @ 2018-01-14 21:39  嘒彼小星  阅读(213)  评论(0编辑  收藏  举报