This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub gyouzasushi/library
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/1160" #include <iostream> #include "datastructure/unionfind.hpp" #include "graph/grid.hpp" int main() { while (true) { int w, h; std::cin >> w >> h; if (h == 0 && w == 0) break; grid::set_bound(h, w); std::vector c(h, std::vector<int>(w)); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { std::cin >> c[y][x]; } } unionfind uf(h * w); for (grid u : grid::grids()) { if (c[u.y][u.x] != 1) continue; for (grid v : u.neighbors_8()) { if (c[v.y][v.x] != 1) continue; uf.unite(u, v); } } int ans = 0; for (grid u : grid::grids()) { if (c[u.y][u.x] == 1 && uf.root(u) == int(u)) { ans++; } } std::cout << ans << '\n'; } }
#line 1 "test/aoj/1160.test.cpp" #define PROBLEM "https://onlinejudge.u-aizu.ac.jp/problems/1160" #include <iostream> #line 2 "datastructure/unionfind.hpp" #include <algorithm> #include <vector> struct unionfind { int n; std::vector<int> data; unionfind(int _n) : n(_n), data(_n, -1) { } int root(int x) { return (data[x] < 0) ? x : data[x] = root(data[x]); } bool unite(int x, int y) { x = root(x); y = root(y); if (x != y) { if (data[y] < data[x]) std::swap(x, y); data[x] += data[y]; data[y] = x; } return x != y; } bool find(int x, int y) { return root(x) == root(y); } int size(int x) { return -data[root(x)]; } std::vector<std::vector<int>> groups() { std::vector<int> root_buf(n), group_size(n); for (int i = 0; i < n; i++) { root_buf[i] = root(i); group_size[root_buf[i]]++; } std::vector<std::vector<int>> ret(n); for (int i = 0; i < n; i++) { ret[i].reserve(group_size[i]); } for (int i = 0; i < n; i++) { ret[root_buf[i]].push_back(i); } ret.erase(std::remove_if( ret.begin(), ret.end(), [&](const std::vector<int>& v) { return v.empty(); }), ret.end()); return ret; } }; #line 3 "graph/grid.hpp" struct grid { public: int y, x; grid() { } grid(int y, int x) : y(y), x(x) { } static void set_bound(int height, int width) { _min_y = 0; _min_x = 0; _max_y = height - 1; _max_x = width - 1; } static void set_bound(int min_y, int min_x, int max_y, int max_x) { _min_y = min_y; _min_x = min_x; _max_y = max_y; _max_x = max_x; } static std::vector<grid> grids() { std::vector<grid> ret; for (int y = _min_y; y <= _max_y; y++) { for (int x = _min_x; x <= _max_x; x++) { ret.emplace_back(y, x); } } return ret; } static grid from(int i) { return grid(i / (_max_x - _min_x + 1) + _min_y, i % (_max_x - _min_x + 1) + _min_x); } bool is_valid() { return _min_y <= y && y <= _max_y && _min_x <= x && x <= _max_x; } std::vector<grid> neighbors() { std::vector<grid> ret; for (auto [dy, dx] : grid::delta) { if (grid(y + dy, x + dx).is_valid()) { ret.emplace_back(y + dy, x + dx); } } return ret; } std::vector<grid> neighbors_8() { std::vector<grid> ret; for (auto [dy, dx] : grid::delta_8) { if (grid(y + dy, x + dx).is_valid()) { ret.emplace_back(y + dy, x + dx); } } return ret; } operator int() const { return (y - _min_y) * (_max_x - _min_x + 1) + (x - _min_x); } private: static inline int _min_y, _min_x, _max_y, _max_x; static inline const std::vector<std::pair<int, int>> delta = { {0, 1}, {1, 0}, {0, -1}, {-1, 0}}; static inline const std::vector<std::pair<int, int>> delta_8 = { {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}; }; #line 6 "test/aoj/1160.test.cpp" int main() { while (true) { int w, h; std::cin >> w >> h; if (h == 0 && w == 0) break; grid::set_bound(h, w); std::vector c(h, std::vector<int>(w)); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { std::cin >> c[y][x]; } } unionfind uf(h * w); for (grid u : grid::grids()) { if (c[u.y][u.x] != 1) continue; for (grid v : u.neighbors_8()) { if (c[v.y][v.x] != 1) continue; uf.unite(u, v); } } int ans = 0; for (grid u : grid::grids()) { if (c[u.y][u.x] == 1 && uf.root(u) == int(u)) { ans++; } } std::cout << ans << '\n'; } }