結果
| 問題 |
No.421 しろくろチョコレート
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-09-09 22:42:44 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 15 ms / 2,000 ms |
| コード長 | 3,356 bytes |
| コンパイル時間 | 1,992 ms |
| コンパイル使用メモリ | 180,456 KB |
| 実行使用メモリ | 6,944 KB |
| 最終ジャッジ日時 | 2024-09-23 07:04:57 |
| 合計ジャッジ時間 | 3,801 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 65 |
ソースコード
#include "bits/stdc++.h"
using namespace std;
#define FOR(i,j,k) for(int (i)=(j);(i)<(int)(k);++(i))
#define rep(i,j) FOR(i,0,j)
#define each(x,y) for(auto &(x):(y))
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define debug(x) cout<<#x<<": "<<(x)<<endl
#define smax(x,y) (x)=max((x),(y))
#define smin(x,y) (x)=min((x),(y))
#define MEM(x,y) memset((x),(y),sizeof (x))
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
struct FlowEdge{
int to, cap, rev;
FlowEdge(int to_, int cap_, int rev_):to(to_),cap(cap_),rev(rev_){ }
};
class FordFulkerson{
public:
FordFulkerson(){}
FordFulkerson(int n) : G(n), used(n){}
void add(int from, int to, int cap){
G[from].emplace_back(to, cap, (int)G[to].size() );
G[to].emplace_back(from, 0, (int)G[from].size() - 1 );
}
int get(int s, int t){
int f = 1, res = 0;
while (f){
fill(begin(used), end(used), false);
f = dfs(s, t, INT_MAX);
res += f;
}
return res;
}
private:
vector<vector<FlowEdge>> G;
vector<bool> used;
int dfs(int v, int t, int f){
if (v == t) return f;
used[v] = 1;
for (auto &e : G[v]){
if (!used[e.to] && e.cap > 0){
int d = dfs(e.to, t, min(e.cap, f));
if (d > 0){
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
};
int maxBipartiteMatching(int n, int m, const vector<int> &u, const vector<int> &v){
const int source = 0, sink = 1, offN = 2, offM = n + 2;
const int V = n + m + 2, cap = 1;
FordFulkerson maxFlow(V);
for(int i = 0; i < n; ++i){
maxFlow.add(source, i + offN, cap);
}
for(int i = 0; i < m; ++i){
maxFlow.add(i + offM, sink, cap);
}
for(int i = 0; i < (int)u.size(); ++i){
maxFlow.add(u[i] + offN, v[i] + offM, cap);
}
return maxFlow.get(source, sink);
}
string nstr(){
static const int MAX_LEN = 101;
static char res_[MAX_LEN];
scanf("%s",res_);
return string(res_);
}
int ww[51][51], bb[51][51];
int main(){
int H, W;
cin >> H >> W;
vector<string> S(H);
rep(y, H)S[y] = nstr();
int wn = 0, bn = 0;
MEM(ww, -1);
MEM(bb, -1);
rep(y, H)rep(x, W){
if(S[y][x] == 'w')ww[y][x] = wn++;
else if(S[y][x] == 'b')bb[y][x] = bn++;
}
vi us, vs;
rep(y, H)rep(x, W){
if(ww[y][x] == -1)continue;
if(x > 0 && bb[y][x - 1] != -1){
us.push_back(ww[y][x]);
vs.push_back(bb[y][x - 1]);
}
if(x < W-1 && bb[y][x+1] != -1){
us.push_back(ww[y][x]);
vs.push_back(bb[y][x+1]);
}
if(y > 0 && bb[y-1][x] != -1){
us.push_back(ww[y][x]);
vs.push_back(bb[y-1][x]);
}
if(y < H-1 && bb[y+1][x] != -1){
us.push_back(ww[y][x]);
vs.push_back(bb[y+1][x]);
}
}
int ps = maxBipartiteMatching(wn, bn, us, vs);
wn -= ps;
bn -= ps;
int ans = ps * 100;
int mi = min(wn, bn);
ans += mi * 10;
wn -= mi;
bn -= mi;
ans += wn + bn;
cout << ans << endl;
}