結果
問題 |
No.421 しろくろチョコレート
|
ユーザー |
![]() |
提出日時 | 2019-02-13 01:33:15 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 6 ms / 2,000 ms |
コード長 | 2,896 bytes |
コンパイル時間 | 885 ms |
コンパイル使用メモリ | 91,508 KB |
最終ジャッジ日時 | 2025-01-06 21:08:56 |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 65 |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:73:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 73 | scanf("%zu %zu", &N, &M); | ~~~~~^~~~~~~~~~~~~~~~~~~ main.cpp:80:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 80 | scanf("%s", buf); | ~~~~~^~~~~~~~~~~
ソースコード
#include <cstdio> #include <cstdint> #include <cassert> #include <vector> #include <string> #include <functional> #include <algorithm> #include <queue> constexpr size_t di[] = {size_t(-1), 0, 1, 0}; constexpr size_t dj[] = {0, size_t(-1), 0, 1}; template <class Weight> struct Edge { size_t src, dst; Weight cost; Edge(size_t src, size_t dst, Weight cost=1): src(src), dst(dst), cost(cost) {} bool operator <(const Edge<Weight> &rhs) const { if (cost != rhs.cost) return cost < rhs.cost; if (src != rhs.src) return src < rhs.src; return dst < rhs.dst; } }; template <class Weight> struct Graph: public std::vector<std::vector<Edge<Weight>>> { Graph(size_t n): std::vector<std::vector<Edge<Weight>>>(n) {} void connect_with(size_t src, size_t dst, Weight cost=1) { (*this)[src].emplace_back(src, dst, cost); (*this)[dst].emplace_back(dst, src, cost); } void connect_to(size_t src, size_t dst, Weight cost=1) { (*this)[src].emplace_back(src, dst, cost); } }; template <class Weight> size_t bipartite_match(const Graph<Weight> &g, size_t mid) { std::vector<size_t> pair(g.size(), -1); std::function<bool (size_t, std::vector<bool> &)> augment; augment = [&](size_t u, std::vector<bool> &visited) { if (u+1 == 0) return true; for (const Edge<Weight> &e: g[u]) { if (visited[e.dst]) continue; visited[e.dst] = true; if (augment(pair[e.dst], visited)) { pair[e.src] = e.dst; pair[e.dst] = e.src; return true; } } return false; }; size_t match = 0; for (size_t i = 0; i < mid; ++i) { std::vector<bool> visited(g.size()); if (augment(i, visited)) ++match; } return match; } int main() { size_t N, M; scanf("%zu %zu", &N, &M); std::vector<std::string> s(N); int w = 0; int b = 0; for (auto& si: s) { char buf[64]; scanf("%s", buf); si = buf; w += std::count(si.begin(), si.end(), 'w'); b += std::count(si.begin(), si.end(), 'b'); } std::vector<std::vector<size_t>> ind(N, std::vector<size_t>(M)); size_t mid; { size_t cur = 0; for (size_t i = 0; i < N; ++i) for (size_t j = i%2; j < M; j += 2) ind[i][j] = cur++; mid = cur; for (size_t i = 0; i < N; ++i) for (size_t j = 1-i%2; j < M; j += 2) ind[i][j] = cur++; } Graph<int> g(N*M); for (size_t i = 0; i < N; ++i) { for (size_t j = 0; j < M; ++j) { if (s[i][j] != 'w') continue; for (int k = 0; k < 4; ++k) { size_t ni = i + di[k]; size_t nj = j + dj[k]; if (!(ni < N && nj < M)) continue; if (s[ni][nj] != 'b') continue; g.connect_with(ind[i][j], ind[ni][nj]); } } } int max = bipartite_match(g, mid); int res = 100*max; w -= max; b -= max; if (w > b) std::swap(w, b); res += 10*w; res += b-w; printf("%d\n", res); }