Cod sursa(job #3335171)

Utilizator MarusCiobanu Marius Marus Data 21 ianuarie 2026 19:47:27
Problema Arbore partial de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.72 kb
//Prim
// #include <bits/stdc++.h>
// #include <fstream>
// using namespace std;
//
// vector<pair<int,int>> adj[200001];
// int parent[200001];       // Vector pentru părinți (nu e folosit în final)
// int viz[200001];
//
// ifstream fin("apm.in");
// ofstream fout("apm.out");
//
// int main() {
//     int n, m;
//     fin >> n >> m;
//
//     for (int i=1;i<=n;i++) {
//         viz[i]=0;
//         parent[i]=-1;
//     }
//
//     int x, y, c;
//     for (int i = 1; i <=m; i++) {
//         fin >> x >> y >> c;
//         adj[x].push_back({y, c});
//         adj[y].push_back({x, c});
//     }
//
//     // Coada de priorități folosită de algoritmul lui Prim:
//     // (cost, nod curent, părinte)
//     priority_queue<
//         tuple<int,int,int>,
//         vector<tuple<int,int,int>>,
//         greater<tuple<int,int,int>>
//     > pq;
//
//     // Începem arborele din nodul 1, cu cost 0 și fără părinte
//     pq.push({0, 1, -1});
//
//     long long totalCost = 0;              // Cost total al APM
//     vector<pair<int,int>> edges;          // Muchiile din APM
//     edges.reserve(n - 1);
//
//     // Algoritmul lui Prim
//     while (pq.size()>0) {
//         auto [cost, nod, par] = pq.top();
//         pq.pop();
//
//         // Dacă nodul este deja inclus în APM, îl ignorăm
//         if (viz[nod]==1) continue;
//
//         viz[nod] = 1;         // Marchează nodul ca selectat în arbore
//         totalCost += cost;        // Adăugăm costul muchiei folosite
//
//         // Dacă nu este nodul de start, adăugăm muchia în lista soluției
//         if (par != -1) {
//             edges.push_back({par, nod});
//         }
//
//         // Explorăm muchiile care pleacă din nod
//         for (auto [vecin,pondere] : adj[nod]) {
//             if (viz[vecin]==0) {
//                 // Adăugăm în coada de priorități candidatul pentru APM
//                 pq.push({pondere, vecin, nod});
//             }
//         }
//     }
//
//     fout<<totalCost<<"\n";
//     fout<<edges.size()<<"\n";     // Nr de muchii în APM (trebuie să fie N - 1)
//     for (auto [u,v] : edges) {
//         fout<<u<<" "<< v<< "\n";
//     }
//
//     return 0;
// }

//Kruscal

#include <bits/stdc++.h>
#include <fstream>
using namespace std;

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


struct muchie {
    int x,y,cost;
};

vector<int> parinte;
vector<int> sz;

void initializeaza_DSU(int n) {
    parinte.resize(n+1);
    sz.resize(n+1);

    for (int i = 1; i <= n; i++) {
        parinte[i] = i;
        sz[i] = 1;
    }
}

int gaseste(int x) {
    if (x == parinte[x])
        return x;
    return parinte[x] = gaseste(parinte[x]);
}

void unifica(int a, int b) {
    if (sz[a] < sz[b])
        swap(a,b);
    parinte[b] = a;
    sz[a] += sz[b];
}

bool arbore(int u, int v) {
    int a = gaseste(u);
    int b = gaseste(v);

    if (a == b) {
        return false;
    }
    unifica(a,b);
    return true;
}

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

    vector<muchie> muchii(M);

    for (int i = 0; i < M; i++) {
        int x,y,c;
        fin>>x>>y>>c;
        muchii[i] = {x,y,c};
    }

    sort(muchii.begin(), muchii.end(), [](muchie a, muchie b) {
        return a.cost < b.cost;
    });

    initializeaza_DSU(N);

    int costTotal = 0;
    vector<pair<int,int>> rezultat;

    for (auto &m: muchii) {
        if (arbore(m.x,m.y)) {
            costTotal += m.cost;
            rezultat.push_back(make_pair(m.x,m.y));
        }
    }

    fout<<costTotal<<endl;
    fout<<rezultat.size()<<endl;
    for (auto &m: rezultat) {
        fout<<m.first<<" "<<m.second<<endl;
    }
}