Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <iomanip>
- #include <cmath>
- #include <queue>
- #include <tuple>
- #include <vector>
- using namespace std;
- struct point {
- int str, col, value;
- point(int s_, int c_, int value_) :
- str(s_), col(c_), value(value_) {}
- };
- int find_root(vector<int> &reps, int vert) {
- vector<int> path;
- while (reps[vert] != vert) {
- path.push_back(vert);
- vert = reps[vert];
- }
- for (size_t i = 0; i < path.size(); ++i) {
- reps[path[i]] = vert;
- }
- return vert;
- }
- void uniot_set(vector<int> &reps, vector<int> &ranks, int first_v, int second_v) {
- int first_root = find_root(reps, first_v);
- int second_root = find_root(reps, second_v);
- if (ranks[first_root] > ranks[second_root]) {
- reps[second_root] = first_root;
- } else if (ranks[first_root] == ranks[second_root]) {
- reps[second_root] = first_root;
- ++ranks[first_root];
- } else {
- reps[first_root] = second_root;
- }
- }
- int main() {
- int N, M;
- cin >> N >> M;
- vector<int> reps(N * M, 0);
- for (int i = 0; i < N * M; ++i) {
- reps[i] = i;
- }
- vector<int> ranks(N * M, 1);
- vector<pair<int, pair<int, int>>> graph;
- for (int i = 0; i < N; ++i) {
- for (int j = 0; j < M; ++j) {
- int cell;
- cin >> cell;
- int first_v = i * M + j;
- int second_v_vert = (i * M + M) + j;
- int second_v_hor = i * M + (j + 1);
- if (cell == 3) {
- if (find_root(reps, first_v) != find_root(reps, second_v_vert) && i != N - 1) {
- uniot_set(reps, ranks, first_v, second_v_vert);
- }
- if (find_root(reps, first_v) != find_root(reps, second_v_hor) && j != M - 1) {
- uniot_set(reps, ranks, first_v, second_v_hor);
- }
- } else if (cell == 2) {
- if (find_root(reps, first_v) != find_root(reps, second_v_hor) && j != M - 1) {
- uniot_set(reps, ranks, first_v, second_v_hor);
- }
- } else if (cell == 1) {
- if (find_root(reps, first_v) != find_root(reps, second_v_vert) && i != N - 1) {
- uniot_set(reps, ranks, first_v, second_v_vert);
- }
- } else if (cell == 0) {
- if (j != M - 1) {
- graph.emplace_back(2, make_pair(first_v, second_v_hor));
- }
- if (i != N - 1) {
- graph.emplace_back(1, make_pair(first_v, second_v_vert));
- }
- }
- }
- }
- sort(graph.begin(), graph.end());
- double cost = 0;
- int count = 0;
- vector<point> points;
- for (size_t i = 0; i < graph.size(); ++i) {
- double weight = graph[i].first;
- int first_v = graph[i].second.first;
- int second_v = graph[i].second.second;
- if (find_root(reps, first_v) != find_root(reps, second_v)) {
- uniot_set(reps, ranks, first_v, second_v);
- cost += weight;
- ++count;
- int str = first_v / M;
- int col = first_v % M;
- points.emplace_back(str, col, weight);
- }
- }
- cout << count << ' ' << cost << '\n';
- for (const auto &point:points) {
- cout << point.str + 1 << " " << point.col + 1 << " " << point.value << "\n";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement