Cod sursa(job #1978517)

Utilizator icansmileSmileSmile icansmile Data 8 mai 2017 02:15:40
Problema Metrou4 Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.94 kb
#include <iostream>
#include<stdio.h>
#include <vector>
#include <cstdlib>
#include <algorithm>

using namespace std;

struct MyEdge {
    int node1;
    int node2;
    long long cost;

    bool operator<(const MyEdge &rhs) const {
        return cost < rhs.cost;
    }
};

class Graph {
public:
    Graph(int n) {
        std::vector<std::pair<int, long long>> temp;
        for (int i = 0; i < n; i++) {
            nodes.push_back(temp);
        }
    }

    std::vector<std::vector<std::pair<int, long long>>> nodes;
    vector<int> parent;
    vector<MyEdge> edges;

    void addEdge(int u, int v, long long cost) {
        nodes[u].push_back(make_pair(v, cost));
        edges.push_back({u, v, cost});
    }

    long long calculateDistance(long long x1, long long y1,
                                long long x2, long long y2) {
        long long d1 = abs(y2 - y1);
        long long d2 = abs(x2 - x1);
        return d1 + d2;
    }

    long long calculateDistance(pair<long long, long long> u,
                                pair<long, long> v) {
        return calculateDistance(u.first, u.second, v.first, v.second);
    }

    vector<MyEdge> getEdges() {
        return edges;
    }

    long long Kruskal() {
        vector<MyEdge> result;
        vector<MyEdge> edges = getEdges();
        sort(edges.begin(), edges.end());
//        for (int i = 0; i < edges.size(); ++i) {
//            cout << edges[i].node1 << " " << edges[i].node2 << " "
//                 << edges[i].cost << endl;
//        }
//        cout << endl << endl << endl;

        //init parent
        for (int i = 0; i < this->nodes.size(); i++) {
            parent.push_back(i);
        }
        for (int i = 0; i < edges.size(); i++) {
            MyEdge myEdge = edges[i];
            int r1 = FindSet(myEdge.node1);
            int r2 = FindSet(myEdge.node2);
            if (r1 != r2) {
                result.push_back(myEdge);
                unionSet(myEdge.node1, myEdge.node2);
            }
        }

        long long sum_costs = 0;
//        cout << "Arbore minim de acoperire:\n";
        for (int i = 0; i < result.size(); ++i) {
//            cout << result[i].node1 << " " << result[i].node2 << " "
//                 << result[i].cost << endl;
            sum_costs = sum_costs + result[i].cost;
        }
//        cout << endl << endl << endl;
        return sum_costs;
    }

    int FindSet(int node) {
        if (parent[node] == node)
            return node;
        else
            return FindSet(parent[node]);
    }

    void unionSet(int node1, int node2) {
        int r1 = FindSet(node1);
        int r2 = FindSet(node2);
        parent[r2] = r1;
    }
};

int main() {
    FILE *f = fopen("metrou4.in", "r");
    FILE *out = fopen("metrou4.out", "w");

    int t;
    fscanf(f, "%d", &t);

    for (int i = 0; i < t; ++i) {
        int n;
        fscanf(f, "%d", &n);
        Graph g = *(new Graph(n));

        vector<pair<long long, long long>> coordinates;

        for (int j = 0; j < n; ++j) {
            int x, y;
            fscanf(f, "%d %d", &x, &y);
            coordinates.push_back({x, y});
        }

        for (int j = 0; j < coordinates.size(); ++j) {
            for (int k = 0; k < coordinates.size(); ++k) {
                if (j != k) {
                    long long cost = g.calculateDistance(coordinates[j],
                                                         coordinates[k]);
                    g.addEdge(j, k, cost);
                }
            }
        }
//        for (int j = 0; j < g.nodes.size(); ++j) {
//            printf("nodul %d cu vecinii:\n", j);
//            for (int k = 0; k < g.nodes[j].size(); ++k) {
//                printf("\tv=%d c=%lld\n", g.nodes[j][k].first,
//                       g.nodes[j][k].second);
//            }
//        }
//        printf("\n\n\n");

        if (i == t - 1) {
            fprintf(out, "%lld", g.Kruskal());
        } else
            fprintf(out, "%lld\n", g.Kruskal());

        g.nodes.clear();
    }
    return 0;
}