結果
| 問題 |
No.421 しろくろチョコレート
|
| ユーザー |
alpha_virginis
|
| 提出日時 | 2016-09-10 01:24:53 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 38 ms / 2,000 ms |
| コード長 | 4,302 bytes |
| コンパイル時間 | 1,746 ms |
| コンパイル使用メモリ | 177,592 KB |
| 実行使用メモリ | 56,592 KB |
| 最終ジャッジ日時 | 2024-09-23 07:08:01 |
| 合計ジャッジ時間 | 4,021 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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 flow
int prev_count[maxV];
void initdfs() {
for(int i = 0; i < V; ++i) {
prev_count[i] = 0;
}
}
int 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]) {
for(int i = prev_count[id]; i < (int)graph[id].size(); ++i) {
prev_count[id] = std::max(prev_count[id], i-1);
std::tuple<int, int> I = graph[id][i];
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;
initdfs();
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;
}
alpha_virginis