[SCOI2007]蜥蜴 题解

[SCOI2007]蜥蜴

板子题啊 , 我好菜啊写错了两次

拆点

拆点后把柱子高度作为边权 , 当前点能到的点相互连边权无限的边 , 如果当前点能到边界 , 就改向汇点连边(注意一个点只能往汇点连最多一条边)

把一开始有蜥蜴的点与源点连边权1的点

然后就没了 

真实板子题

我菜啊

  1 #include<cmath>
  2 #include<queue>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<iostream>
  7 #include<algorithm>
  8 #define APART puts("----------------------")
  9 #define debug 1
 10 #define FILETEST 0
 11 #define inf 10010
 12 #define ll long long
 13 #define ha 998244353
 14 #define INF 0x7fffffff
 15 #define INF_T 9223372036854775807
 16 #define DEBUG printf("%s %d\n",__FUNCTION__,__LINE__)
 17 
 18 namespace chino{
 19 
 20 inline void setting(){
 21 #if FILETEST
 22     freopen("test.in", "r", stdin);
 23     freopen("test.me.out", "w", stdout);
 24 #endif
 25     return;
 26 }
 27 
 28 inline int read(){
 29     char c = getchar(), up = c; int num = 0;
 30     for(; c < '0' || c > '9'; up = c, c = getchar());
 31     for(; c >= '0' && c <= '9'; num = (num << 3) + (num << 1) + (c ^ '0'), c = getchar());
 32     return  up == '-' ? -num : num;
 33 }
 34 
 35 int n, m, d;
 36 int cntE = -1;
 37 int S, T;
 38 int maxflow, totL;
 39 int dep[inf];
 40 int head[inf];
 41 int cur[inf];
 42 char str[inf][inf];
 43 struct Edge{
 44     int to;
 45     int flow;
 46     int next;
 47 }e[inf << 1];
 48 std::queue <int> Q;
 49 
 50 inline void AddEdge(int from, int to, int flow){
 51     ++cntE;
 52     e[cntE].to = to;
 53     e[cntE].flow = flow;
 54     e[cntE].next = head[from];
 55     head[from] = cntE;
 56     return;
 57 }
 58 
 59 inline bool check(int x, int y){
 60     return x < 1 || y < 1 || x > n || y > m;
 61 }
 62 
 63 inline bool checkGG(int x, int y){
 64     return sqrt(x * x + y * y) > d;
 65 }
 66 
 67 inline bool BFS(int s, int t){
 68     memset(dep, -1, sizeof dep);
 69     memcpy(cur, head, sizeof cur);
 70     while(!Q.empty())
 71         Q.pop();
 72     dep[s] = 1;
 73     Q.push(s);
 74     while(!Q.empty()){
 75         int x = Q.front();
 76         Q.pop();
 77         for(int i = head[x]; i ^ -1; i = e[i].next){
 78             int y = e[i].to;
 79             if(dep[y] == -1 && e[i].flow){
 80                 dep[y] = dep[x] + 1;
 81                 Q.push(y);
 82             }
 83         }
 84     }
 85     return dep[t] ^ -1;
 86 }
 87 
 88 int DFS(int s, int limit){
 89     if(limit == 0 || s == T)
 90         return limit;
 91     int f = 0;
 92     int flow = 0;
 93     for(int i = cur[s]; i ^ -1; i = e[i].next){
 94         cur[s] = i;
 95         int Min = std::min(limit, e[i].flow);
 96         int to = e[i].to;
 97         if(dep[to] == dep[s] + 1 && (f = DFS(to, Min))){
 98             flow += f;
 99             limit -= f;
100             e[i].flow -= f;
101             e[i ^ 1].flow += f;
102             if(limit == 0)
103                 break;
104         }
105     }
106     return flow;
107 }
108 
109 inline void dinic(int s, int t){
110     while(BFS(s, t))
111         maxflow += DFS(s, INF);
112     return; 
113 }
114 
115 inline int main(){
116     memset(head, -1, sizeof head);
117     n = read();
118     m = read();
119     d = read();
120     S = n * m + 1;
121     T = S + 1;
122     S <<= 1, T <<= 1;
123     for(int i = 1; i <= n; i++)
124         scanf("%s", str[i] + 1);
125     for(int i = 1; i <= n; i++){
126         for(int j = 1; j <= m; j++){
127             bool flag = 0;
128             int now = str[i][j] - '0';
129             if(now == 0)
130                 continue;
131             AddEdge(i * m - m + j, (i * m - m + j) + n * m, now);
132             AddEdge((i * m - m + j) + n * m, i * m - m + j, 0);
133             for(int a = -d; a <= d; a++){
134                 for(int b = -d; b <= d; b++){
135                     int nowx = i + a;
136                     int nowy = j + b;
137                     if(str[nowx][nowy] == '0' || checkGG(a, b) || (a == 0 && b == 0))
138                         continue;
139                     if(check(nowx, nowy)){
140                         if(flag == 0){
141                             AddEdge((i * m - m + j) + n * m, T, INF);
142                             AddEdge(T, (i * m - m + j) + n * m, 0);
143                             flag = 1;
144                         }
145                     } else {
146                         AddEdge((i * m - m + j) + n * m, nowx * m - m + nowy, INF);
147                         AddEdge(nowx * m - m + nowy, (i * m - m + j) + n * m, 0);
148                     }
149                 }
150             }
151         }
152     }
153     for(int i = 1; i <= n; i++)
154         scanf("%s", str[i] + 1);
155     for(int i = 1; i <= n; i++){
156         for(int j = 1; j <= m; j++)
157             if(str[i][j] == 'L'){
158                 AddEdge(S, i * m - m + j, 1);
159                 AddEdge(i * m - m + j, S, 0);
160                 ++totL;
161             }
162     }
163     dinic(S, T);
164     printf("%d\n", totL - maxflow);
165     return 0;
166 }
167 
168 }//namespace chino
169 
170 int main(){return chino::main();}

 

posted @ 2019-08-30 20:47  ChiaroShiro  阅读(101)  评论(0编辑  收藏  举报