View difference between Paste ID: ervimVJN and qGq5Crzk
SHOW: | | - or go back to the newest paste.
1
//WA
2
#include <iostream>
3
#include <cstdio>
4
#include <vector>
5
#include <cstring>
6
#include <cmath>
7
#include <map>
8
#include <set>
9
#include <algorithm>
10
#include <queue>
11
#include <stack>
12
#include <sstream>
13
#include <ctime>
14
15
using namespace std;
16
17
typedef pair < int, int >     pii;
18
typedef long long int         i64;
19
typedef vector < pii >        vpii;
20
typedef pair < i64, i64 >     pi64;
21
typedef vector < int >        vi;
22
typedef vector < vi >         vvi;
23
24
#define rep(i,a,b)            for(int i=(int)a; i<(int)b; ++i)
25
#define rep_it(s,a,b)         for(s :: iterator it=a; it!= b; it++)
26
#define mp                    make_pair
27
#define pb                    push_back
28
#define clr(v)                v.clear()
29
#define mset(a,x)	      memset(a, x, sizeof a)
30
#define all(v)                v.begin(), v.end()
31
#define err                   1E-8
32
#define inf                   (1<<29)
33
#define MAX                   1000
34
35-
//#define inf_4                 0x04040404 //   67372036 ** 27
35+
36-
//#define inf_8                 0x08080808 //  134744072 ** 28
36+
37-
//#define inf_16                0x10101010 //  269488144 ** 29
37+
38-
//#define inf_32                0x20202020 //  538976288 ** 30
38+
39-
//#define inf_64                0x40404040 // 1077952576 ** 31
39+
40-
//#define inf_127               0x7f7f7f7f // 2139062143 ** 31
40+
41
42
void augment(int u, int ed){
43
   if(u == S) f = ed;
44
   else if(p[u] != -1){
45
      augment(p[u], min(res[p[u]][u], ed));
46
      res[p[u]][u] -= f;
47
      res[u][p[u]] += f;
48
   }
49
}
50
51
int maxFlow(int N){
52
   mf = 0;
53
   int u;
54
   do{
55
      f = 0;
56
57
      p = vi(N, -1);
58
      vi dist(N, inf);
59
      queue < int > Q;
60
      Q.push(S);
61
      dist[S] = 0;
62
63
      while(!Q.empty()){
64
	 u = Q.front(); Q.pop();
65
	 if(u == T) break;
66
	 rep(v,0,N) if(res[u][v] > 0 && dist[v]==inf)
67
	    dist[v]=dist[u]+1, p[v]=u, Q.push(v);
68
      }
69
      augment(T, inf);
70
      mf += f;
71
   }while(f != 0);
72
}
73
74
#define can(_i,_j) (_i>=0 && _j>=0 && _i<R && _j<C)
75
76
int main(){
77
   int nT, cont;
78
   bool op;
79
   int ir, ic, u, v;
80
   vpii ast;
81
   map < pii, int > mapa;
82
   //char str[21];
83
   string str;
84
   //scanf("%d\n", &nT);
85
   cin >> nT;
86
   while(nT--){
87
      cont = 1;
88
      clr(ast); clr(mapa);
89
      mset(taken, false); mset(res, 0);
90
91
      //scanf("%d%d\n", &R, &C);
92
      cin >> R >> C;
93
      rep(i,0,R){
94
	 //scanf("%s\n", str);
95
	 cin >> str;
96
	 rep(j,0,C) if(str[j] == '*') ast.pb(mp(i,j)), mapa[(mp(i,j))] = cont++;
97
	 rep(j,0,C) M[i][j]=str[j];
98
      }
99
      S = 0;
100
      T = cont;
101
      
102
      rep(i,0,ast.size()){
103
	 ir = ast[i].first;
104
	 ic = ast[i].second;
105
	 if(!taken[ir][ic]){
106
	    queue < pii > Q;
107
	    M[ir][ic] = (ir + ic) % 2 == 0 ? 'A' : 'B';
108
	    Q.push(mp(ir, ic));
109
	    while(!Q.empty()){
110
	       ir = Q.front().first;
111
	       ic = Q.front().second;
112
	       Q.pop();
113
114
	       if(taken[ir][ic]) continue;
115
116
	       op = (M[ir][ic] == 'A');
117
	       taken[ir][ic] = true;
118
	       u = mapa[mp(ir, ic)];
119
120
	       if(op) res[S][u] = 1;
121
	       else res[u][T] = 1;
122
123
	       rep(m,0,4) if(can(ir + mR[m], ic + mC[m]) && M[ir + mR[m]][ic + mC[m]] == '*'){
124
		  M[ir + mR[m]][ic + mC[m]] = op ? 'B' : 'A';
125
		  Q.push(mp(ir + mR[m], ic + mC[m]));
126
		  
127
		  v = mapa[mp(ir + mR[m], ic + mC[m])];
128
		  if(op) res[u][v] = 1;
129
		  else res[v][u] = 1;
130
	       }
131
	    }
132
	 }
133
      }
134
135
      //rep(i,0,R){rep(j,0,C) cout << M[i][j]; cout << endl;}
136
137
      maxFlow(T+1);
138
      //printf("%d\n", cont - 1 - mf);
139
      cout << (cont - 1 - mf) << endl;
140
   }
141
   return 0;
142
}