Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- enum EEdgeCost
- {
- EC_VERTICAL = 1,
- EC_HORIZONTAL = 2
- };
- class TDisjointSetUnion {
- public:
- unsigned Components;
- std::vector<unsigned> Parent;
- std::vector<unsigned> Rank;
- public:
- TDisjointSetUnion(unsigned c) : Components(c), Parent(Components), Rank(Components, 0) {
- for (unsigned i = 0; i < Components; ++i) {
- Parent[i] = i;
- }
- }
- unsigned FindSet(unsigned x) {
- if (Parent[x] == x) {
- return x;
- } else {
- Parent[x] = FindSet(Parent[x]);
- return Parent[x];
- }
- }
- void UniteSets(unsigned x, unsigned y) {
- x = FindSet(x);
- y = FindSet(y);
- if (x != y) {
- if (Rank[x] < Rank[y]) {
- Parent[x] = y;
- } else {
- Parent[y] = x;
- if (Rank[x] == Rank[y]) {
- ++Rank[x];
- }
- }
- --Components;
- }
- }
- };
- void Input(TDisjointSetUnion& t, unsigned h, unsigned w) {
- for (unsigned i = 0; i < h; ++i) {
- for (unsigned j = 0; j < w; ++j) {
- unsigned v;
- std::cin >> v;
- if (v & 1) {
- t.UniteSets(i * w + j, (i + 1) * w + j);
- }
- if ((v >> 1) & 1) {
- t.UniteSets(i * w + j, i * w + (j + 1));
- }
- }
- }
- }
- std::vector<std::pair<unsigned, unsigned>> Connect(TDisjointSetUnion& t, unsigned h, unsigned w) {
- std::vector<std::pair<unsigned, unsigned>> added;
- for (unsigned i = 0; i < h - 1; ++i) {
- for (unsigned j = 0; j < w; ++j) {
- if (t.FindSet(i * w + j) != t.FindSet((i + 1) * w + j)) {
- added.push_back(std::make_pair(i * w + j, EC_VERTICAL));
- t.UniteSets(i * w + j, (i + 1) * w + j);
- }
- }
- }
- for (unsigned i = 0; i < h; ++i) {
- for (unsigned j = 0; j < w - 1; ++j) {
- if (t.FindSet(i * w + j) != t.FindSet(i * w + (j + 1))) {
- added.push_back(std::make_pair(i * w + j, EC_HORIZONTAL));
- t.UniteSets(i * w + j, i * w + (j + 1));
- }
- }
- }
- return added;
- }
- int main() {
- unsigned n, m;
- std::cin >> n >> m;
- TDisjointSetUnion grid(n * m);
- Input(grid, n, m);
- std::vector<std::pair<unsigned, unsigned>> added = Connect(grid, n, m);
- unsigned cost = 0;
- for (auto bridge: added) {
- cost += bridge.second;
- }
- std::cout << added.size() << " " << cost << std::endl;
- for (auto bridge: added) {
- std::cout << bridge.first / m + 1 << " " << bridge.first % m + 1 << " " << bridge.second << std::endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement