Cod sursa(job #3251287)

Utilizator Delian_04Dan Delian Delian_04 Data 25 octombrie 2024 16:40:15
Problema Arbore partial de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.36 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <climits>
#define DIMMAX 2000001
using namespace std;

ifstream fin("apm.in");
ofstream fout("apm.out");

vector<int> d; // minimum cost vector

int Parent(int i) { return i / 2; }
int Left(int i) { return 2 * i; }
int Right(int i) { return 2 * i + 1; }

void HeapUp(int h[], vector<int>& posInHeap, int i) {
    while (i > 1 && d[h[Parent(i)]] > d[h[i]]) {
        swap(posInHeap[h[i]], posInHeap[h[Parent(i)]]);
        swap(h[i], h[Parent(i)]);
        i = Parent(i);
    }
}

void MinHeapify(int h[], vector<int>& posInHeap, int i, int dim_heap) {
    int smallest = i;
    int l = Left(i);
    int r = Right(i);

    if (l <= dim_heap && d[h[l]] < d[h[smallest]])
        smallest = l;
    if (r <= dim_heap && d[h[r]] < d[h[smallest]])
        smallest = r;

    if (smallest != i) {
        swap(posInHeap[h[i]], posInHeap[h[smallest]]);
        swap(h[i], h[smallest]);
        MinHeapify(h, posInHeap, smallest, dim_heap);
    }
}

int HeapExtractMin(int h[], vector<int>& posInHeap, int& dim_heap) {
    if (dim_heap < 1)
        return -1;
    int minNode = h[1];
    h[1] = h[dim_heap];
    posInHeap[h[1]] = 1;
    dim_heap--;
    MinHeapify(h, posInHeap, 1, dim_heap);
    return minNode;
}

void BuildMinHeap(int h[], vector<int>& posInHeap, int dim_heap) {
    for (int i = dim_heap / 2; i >= 1; i--)
        MinHeapify(h, posInHeap, i, dim_heap);
}

vector<vector<pair<int, int>>> generare_lista_adiacenta(int varfuri, int muchii) {
    vector<vector<pair<int, int>>> lista(varfuri);
    int x, y, cost;
    for (int i = 0; i < muchii; i++) {
        fin >> x >> y >> cost;
        lista[x - 1].push_back({ y, cost });
        lista[y - 1].push_back({ x, cost });
    }
    return lista;
}

void Prim(int n, int m, int s, vector<vector<pair<int, int>>>& lista_adiacenta_cu_cost,
          vector<pair<int, int>>& muchii_apcm, long long& cost) {
    int h[n + 1];
    vector<int> posInHeap(n + 1);

    for (int i = 1; i <= n; i++) {
        h[i] = i;
        posInHeap[i] = i;
    }

    d.resize(n + 1, INT_MAX);
    vector<int> tata(n + 1, 0);
    d[s] = 0;
    int dim_heap = n;
    BuildMinHeap(h, posInHeap, dim_heap);

    vector<bool> inHeap(n + 1, true);

    while (dim_heap) {
        int u = HeapExtractMin(h, posInHeap, dim_heap);
        inHeap[u] = false;

        for (const auto& muchie : lista_adiacenta_cu_cost[u - 1]) {
            int v = muchie.first;
            int cost_muchie = muchie.second;

            if (inHeap[v] && cost_muchie < d[v]) {
                d[v] = cost_muchie;
                tata[v] = u;

                int i = posInHeap[v];
                HeapUp(h, posInHeap, i);
            }
        }
    }

    for (int i = 1; i <= n; i++)
        if (i != s)
            muchii_apcm.push_back({ i, tata[i] }), cost += d[i];
}

int main() {
    int n, m;
    fin >> n >> m;
    vector<vector<pair<int, int>>> lista_adiacenta_cu_cost = generare_lista_adiacenta(n, m);
    fin.close();

    vector<pair<int, int>> muchii_apcm;
    long long cost = 0;

    Prim(n, m, 1, lista_adiacenta_cu_cost, muchii_apcm, cost);

    fout << cost << '\n' << n - 1 << '\n';
    for (const auto& muchie : muchii_apcm)
        fout << muchie.first << " " << muchie.second << '\n';
    fout.close();
    return 0;
}