結果
問題 | No.421 しろくろチョコレート |
ユーザー |
![]() |
提出日時 | 2016-09-10 01:09:26 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 70 ms / 2,000 ms |
コード長 | 4,026 bytes |
コンパイル時間 | 1,767 ms |
コンパイル使用メモリ | 177,528 KB |
実行使用メモリ | 232,104 KB |
最終ジャッジ日時 | 2024-09-23 07:07:30 |
合計ジャッジ時間 | 6,173 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 65 |
ソースコード
#include <bits/stdc++.h>char field[64][64];int h, w;int dr[4] = {1, 0, -1, 0};int dc[4] = {0, 1, 0, -1};bool outOfRange(int r, int c) {if( not ( 0 <= r and r < h and 0 <= c and c < w ) ) return true;return false;}const int INF = (1 << 29);const int maxV = 64 * 64 * 2;std::vector< std::tuple<int, int> > graph[maxV];bool finished[maxV];int flow[maxV][maxV], capacity[maxV][maxV];int depth[maxV];int src, dest;int V, E;void setupDinic() {V = 64 * 64 * 2;for(int r = 0; r < h; ++r) {for(int c = 0; c < w; ++c) {if( field[r][c] == '.' ) continue;if( field[r][c] == 'b' ) {int s = 64 * 64 - 1;int t = 64 * r + c;// printf("src to b(%d, %d)\n", r, c);graph[s].push_back(std::make_tuple(t, 1));graph[t].push_back(std::make_tuple(s, 0));capacity[s][t] = 1;capacity[t][s] = 0;for(int k = 0; k < 4; ++k) {int nr = r + dr[k], nc = c + dc[k];if( outOfRange(nr, nc) ) continue;if( field[nr][nc] == '.' ) continue;int s2 = t;int t2 = 64 * 64 + 64 * nr + nc;// printf("b(%d, %d) to w(%d, %d)\n", r, c, nr, nc);graph[s2].push_back(std::make_tuple(t2, 1));graph[t2].push_back(std::make_tuple(s2, 0));capacity[s2][t2] = 1;capacity[t2][s2] = 0;}}if( field[r][c] == 'w' ) {int s = 64 * 64 + 64 * r + c;int t = 2 * 64 * 64 - 1;// printf("w(%d, %d) to dest\n", r, c);graph[s].push_back(std::make_tuple(t, 1));graph[t].push_back(std::make_tuple(s, 0));capacity[s][t] = 1;capacity[t][s] = 0;}}}// scanf("%d %d", &V, &E);// for(int i = 0; i < E; ++i) {// int s, t, c;// scanf("%d %d %d", &s, &t, &c);// graph[s].push_back(std::make_tuple(t, c));// graph[t].push_back(std::make_tuple(s, 0));// capacity[s][t] = c;// capacity[t][s] = 0;// }src = 64 * 64 - 1;dest = 2 * 64 * 64 - 1;}// update depth (foreach, update depth[next])void bfs() {for(int i = 0; i < V; ++i) {depth[i] = INF;}depth[src] = 0;int limitdepth = INF;std::queue<int> q;q.push(src);while( not q.empty() ) {int id = q.front(); q.pop();if( id == dest ) limitdepth = depth[id];if( depth[id] > limitdepth ) break;for(std::tuple<int, int> I : graph[id]) {int next, limit;std::tie(next, limit) = I;if( limit - flow[id][next] <= 0 ) continue;if( depth[next] != INF ) continue;depth[next] = depth[id] + 1;q.push(next);}}// printf("update depth\n");for(int i = 0; i < V; ++i) {// printf("depth[%d] : %d\n", i, depth[i]);}}// try flow once// return := one flowint dfs(int id, int fm) {if( id == dest ) return fm;if( fm == 0 ) return 0;if( finished[id] ) return 0;for(std::tuple<int, int> I : graph[id]) {int next, limit;std::tie(next, limit) = I;if( not ( depth[id] < depth[next] ) ) continue;int ft = dfs(next, std::min(fm, limit - flow[id][next]));if( ft <= 0 ) continue;flow[id][next] += ft;flow[next][id] -= ft;return ft;}finished[id] = true;return 0;}int Dinic() {int total = 0;for(;;) {bfs();for(int i = 0; i < V; ++i) finished[i] = false;int f = 0;for(;;) {int ft = dfs(src, INF);if( ft == 0 ) break;f += ft;}if( f == 0 ) break;total += f;}return total;}int main() {scanf("%d %d", &h, &w);for(int i = 0; i < h; ++i) {scanf("%s", field[i]);}setupDinic();int num_pair = Dinic();// printf(" %d\n", num_pair);int ww = 0, bb = 0;for(int r = 0; r < h; ++r) {for(int c = 0; c < w; ++c) {if( field[r][c] == 'w' ) ww += 1;if( field[r][c] == 'b' ) bb += 1;}}ww -= num_pair;bb -= num_pair;printf("%d\n", 100 * num_pair + 10 * std::min(ww, bb) + std::abs(ww - bb));return 0;}