結果
問題 | No.421 しろくろチョコレート |
ユーザー |
|
提出日時 | 2021-02-16 21:39:58 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 5 ms / 2,000 ms |
コード長 | 4,326 bytes |
コンパイル時間 | 1,832 ms |
コンパイル使用メモリ | 145,136 KB |
最終ジャッジ日時 | 2025-01-18 21:33:12 |
ジャッジサーバーID (参考情報) |
judge3 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 65 |
ソースコード
#include <iostream>#include <vector>#include <algorithm>#include <cmath>#include <queue>#include <string>#include <map>#include <set>#include <stack>#include <tuple>#include <deque>#include <array>#include <numeric>#include <bitset>#include <iomanip>#include <cassert>#include <chrono>#include <random>#include <limits>#include <iterator>#include <functional>#include <sstream>#include <fstream>#include <complex>#include <cstring>#include <unordered_map>#include <unordered_set>using namespace std;using ll = long long;constexpr int INF = 1001001001;constexpr int mod = 1000000007;// constexpr int mod = 998244353;template<class T>inline bool chmax(T& x, T y){if(x < y){x = y;return true;}return false;}template<class T>inline bool chmin(T& x, T y){if(x > y){x = y;return true;}return false;}template<typename flow_t>struct Dinic{const flow_t INF;struct Edge{int to;flow_t cap;int rev;bool isrev;Edge(int to, flow_t cap, int rev, bool isrev) : to(to), cap(cap), rev(rev), isrev(isrev) {}};vector<vector<Edge>> graph;vector<int> min_cost; // sからの距離(bfsで調べる)vector<int> iter; // どこまで調べ終わったか(dfs時に使用)Dinic(int V) : INF(numeric_limits<flow_t>::max() / 2){graph.resize(V);}void add_edge(int from, int to, flow_t cap){graph[from].push_back(Edge(to, cap, graph[to].size(), false));graph[to].push_back(Edge(from, 0, graph[from].size() - 1, true));}// 最短路探索bool bfs(int s, int t){min_cost.assign(graph.size(), -1);queue<int> que;min_cost[s] = 0;que.push(s);while(!que.empty() && min_cost[t] == -1){int p = que.front();que.pop();for(auto &e : graph[p]){if(e.cap > 0 && min_cost[e.to] == -1){min_cost[e.to] = min_cost[p] + 1;que.push(e.to);}}}return min_cost[t] != -1;}flow_t dfs(int v, int t, flow_t flow){if(v == t) return flow;for(int &i = iter[v]; i < (int)graph[v].size(); ++i){Edge &e = graph[v][i];if(e.cap > 0 && min_cost[v] < min_cost[e.to]){flow_t d = dfs(e.to, t, min(flow, e.cap));if(d > 0){e.cap -= d;graph[e.to][e.rev].cap += d;return d;}}}return 0;}flow_t max_flow(int s, int t){flow_t flow = 0;// 最短路を求めて、そのパスに最大流を流すwhile(bfs(s, t)){iter.assign(graph.size(), 0);flow_t f = 0;while((f = dfs(s, t, INF)) > 0) flow += f;}return flow;}};constexpr int dx[4] = {1, 0, -1, 0};constexpr int dy[4] = {0, 1, 0, -1};int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int N, M, white = 0, black = 0;cin >> N >> M;vector<vector<int>> S(N, vector<int>(M));Dinic<int> d(N * M + 2);int s = N * M, t = s + 1;for(int i = 0; i < N; ++i){for(int j = 0; j < M; ++j){char ch;cin >> ch;if(ch == 'w'){white += 1;S[i][j] = 1;}else if(ch == 'b'){black += 1;S[i][j] = -1;}if((i + j) % 2 == 0) d.add_edge(s, M * i + j, 1);else d.add_edge(M * i + j, t, 1);}}for(int x = 0; x < N; ++x){for(int y = 0; y < M; ++y){if((x + y) % 2 == 1) continue;for(int i = 0; i < 4; ++i){int nx = x + dx[i], ny = y + dy[i];if(nx < 0 || nx >= N || ny < 0 || ny >= M) continue;if(S[x][y] * S[nx][ny] == -1){d.add_edge(M * x + y, M * nx + ny, 1);}}}}int match = d.max_flow(s, t);cout << match * 100 + (min(white, black) - match) * 10 + max(white, black) - min(white, black) << endl;return 0;}