競程作業,以前交大年度賽的題目:FOJ-254
Flow network,把源點指向所有的 H,然後 H 指向 B,B 指向 T,T 指向匯點 然後跑 Edmonds–Karp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 # include <bits/stdc++.h> using namespace std ;# define ll long long # define ui unsigned int # define ull unsigned long long # define INF 1023456789 # define jizz cin.tie(0);ios_base::sync_with_stdio(0); void solve () { int n, m, t, s=0 ; char tmpc; cin >>n>>m; t = n*m+1 ; vector <vector <int >> M (n+1 , vector <int >(m+1 )) ; vector <vector <int >> adj (n*m+4 , vector <int >(n*m+4 , 0 )) ; for (int i=0 ; i<n; i++){ for (int j=1 ; j<=m; j++){ cin >>tmpc; if (tmpc=='H' ) M[i][j] = 0 ; else if (tmpc=='B' ) M[i][j] = 1 ; else M[i][j] = 2 ; if (i>0 ){ if (M[i-1 ][j]==M[i][j]+1 ){ adj[i*m+j][(i-1 )*m+j] = 1 ; } if (M[i-1 ][j]==M[i][j]-1 ){ adj[(i-1 )*m+j][i*m+j] = 1 ; } } if (j>1 ){ if (M[i][j-1 ]==M[i][j]+1 ){ adj[i*m+j][i*m+j-1 ] = 1 ; } if (M[i][j-1 ]==M[i][j]-1 ){ adj[i*m+j-1 ][i*m+j] = 1 ; } } if (M[i][j]==0 ){ adj[s][i*m+j] = 1 ; } if (M[i][j]==2 ){ adj[i*m+j][t] = 1 ; } } } int now, l, ans=0 , dot, f; while (1 ){ int i; queue <int > Q; vector <bool > visited (n*m+4 , 0 ) ; vector <int > bt (n*m+4 ) ; bt[s] = -1 ; Q.push(s); while (!Q.empty()){ now = Q.front(); Q.pop(); for (i=1 ; i<=n*m+1 ; i++){ if (adj[now][i]&&!visited[i]){ bt[i] = now; visited[i] = 1 ; if (i==t) break ; Q.push(i); } } if (i==t) break ; } if (i!=t){ for (int j=1 ; j<=n*m; j++){ if (adj[t][j]) ans++; } cout <<ans<<"\n" ; return ; } dot = t; while (dot!=s){ adj[dot][bt[dot]]++; adj[bt[dot]][dot]--; dot = bt[dot]; } } } int main () {jizz int t; cin >>t; while (t--){ solve(); } }