Cod sursa(job #2807447)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 23 noiembrie 2021 20:05:02
Problema Arbore partial de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

ifstream f("apm.in");
ofstream g("apm.out");

typedef pair < int, int > PII;
typedef pair < int, PII > Edge;

const int MMAX = 4e5 + 1;

int N, M;

vector < Edge > Edges;
bool Sel[MMAX];

class DisjointSet
{
    static const int NMAX = 2e5 + 1;

    int T[NMAX];
    int Size[NMAX];

private:
    inline int Find (int X)
    {
        if(X == T[X])
            return X;

        return (T[X] = Find(T[X]));
    }

    inline void my_swap (int &x, int &y)
    {
        x = (x ^ y), y = (x ^ y), x = (x ^ y);

        return;
    }

public:
    inline void Initialize (int N)
    {
        for(int i = 1; i <= N; ++i)
            T[i] = i, Size[i] = 1;

        return;
    }

    inline bool Unify (int X, int Y)
    {
        X = Find(X);
        Y = Find(Y);

        if(X == Y)
            return 0;

        if(Size[X] < Size[Y])
            my_swap(X, Y);

        T[Y] = X, Size[X] += Size[Y], Size[Y] = 0;

        return 1;
    }
} Set;

static inline void Read ()
{
    f.tie(nullptr);

    f >> N >> M;

    for(int i = 1; i <= M; ++i)
    {
        int x = 0, y = 0, c = 0;
        f >> x >> y >> c;

        Edges.push_back({c, {x, y}});
    }

    return;
}

static inline void Solve ()
{
    sort(Edges.begin(), Edges.end());

    int ans = 0;

    Set.Initialize(N);

    for(int i = 0; i < M; ++i)
        if(Set.Unify(Edges[i].second.first, Edges[i].second.second))
            ans += Edges[i].first, Sel[i] = 1;

    g << ans << '\n';

    return;
}

static inline void Write ()
{
    g << (N - 1) << '\n';

    for(int i = 0; i < M; ++i)
        if(Sel[i])
            g << Edges[i].second.first << ' ' << Edges[i].second.second << '\n';

    return;
}

int main()
{
    Read();

    Solve();

    Write();

    return 0;
}