Cod sursa(job #3337017)

Utilizator iulia_learning_timeLearning Time iulia_learning_time Data 26 ianuarie 2026 20:38:37
Problema Arbore partial de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.89 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm> // Pentru sortare (opțional, doar pt estetică la output)
using namespace std;

const int INF = 1e9;

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


void Prim(vector<vector<pair<int, int>>> adj, int N){
      // Min-heap care stochează: {cost, {nod_curent, nod_parinte}}
    // Avem nevoie de nod_parinte ca să putem afișa muchia care a fost aleasă
    priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>> > pq;
    // pair<int, pair<int, int>> // ce fel de obiecte vom stoca in priority_queue, Structura arată așa: { cost, { nod_destinatie, nod_sursa } }.
    // vector<pair<int, pair<int, int>>> // priority_queue nu stochează datele direct "în aer", ci folosește un container standard în spate (de obicei un vector).
    // greater<pair<int, pair<int, int>>> > //greater: Inversează ordinea și transformă coada într-un Min-Heap
    //Acum, pq.top() îți va returna elementul care este "mai mic" conform comparatorului greater.

    vector<bool> visited(N + 1, false);
    
    // Pentru a stoca muchiile soluției (cele N-1 muchii)
    vector<pair<int, int>> mst_edges;
    int total_cost = 0;

    // Începem cu nodul 1. Cost 0, Părinte -1 (nu are)
    pq.push({0, {1, -1}});

    while (!pq.empty()) {
        auto top = pq.top();
        pq.pop();

        // { cost, { nod_destinatie, nod_sursa } }
        int cost = top.first;
        int u = top.second.first;
        int prev = top.second.second; // Nodul din care am venit

        // Dacă nodul e deja vizitat, îl ignorăm
        if (visited[u]) 
            continue;

        // Marchem nodul ca vizitat
        visited[u] = true;

        // Dacă nu e nodul de start, adăugăm muchia la soluție
        if (prev != -1) {
            total_cost += cost;
            mst_edges.push_back({prev, u});
        }

        // Adăugăm vecinii
        for (auto &edge : adj[u]) {
            int v = edge.first;
            int weight = edge.second;

            if (!visited[v]) {
                // Adăugăm în coadă: costul, nodul destinație, și nodul curent (ca părinte)
                pq.push({weight, {v, u}});
            }
        }
    }

    // Afișare rezultate conform formatului din imagine
    fout << total_cost << "\n";
    fout << mst_edges.size() << "\n"; // Ar trebui să fie N-1

    for (auto &edge : mst_edges) {
        fout << edge.first << " " << edge.second << "\n";
    }
}



int main() {
    int N, M;
    fin >> N >> M;

    // Lista de adiacență: adj[nod] = {vecin, cost}
    // Folosim N + 1 pentru că nodurile sunt indexate de la 1
    vector<vector<pair<int, int>>> adj(N + 1);

    for (int i = 0; i < M; i++) {
        int u, v, c;
        fin >> u >> v >> c;
        adj[u].push_back({v, c});
        adj[v].push_back({u, c});
    }


    Prim(adj, N);   
    return 0;
}