Pagini recente » Cod sursa (job #312161) | Cod sursa (job #2456180) | Cod sursa (job #2407139) | Cod sursa (job #3003256) | Cod sursa (job #2857466)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
//determina arborele partial de cost minim
//100p
ifstream fin("apm.in");
ofstream fout("apm.out");
const int MAX = 200005, INF = (1 << 30);
int n, m;
int costNod[MAX], tata[MAX]; int costTotal = 0;
bool inArbore[MAX];
struct Compara //criteriu de ordonare crescatoare a heap-ului,
{ //in functie de costul muchiei care duce la acel nod
bool operator() (pair < int, int > x, pair < int, int > y)
{
return (x.second > y.second);
}
};
priority_queue < pair < int, int >, vector < pair < int, int > >, Compara > heap;
//heap-ul va retine indicele unui nod si distanta dintre arbore si acel nod
vector < pair < int, int > > drum[MAX];
void Citire()
{
fin >> n >> m;
for (int i = 1; i <= m; i++)
{
int x, y, cost;
fin >> x >> y >> cost;
drum[x].push_back(make_pair(y, cost));
drum[y].push_back(make_pair(x, cost));
}
}
void Prim()
{
for (int i = 2; i <= n; i++) //costul fiecarui nod (mai putin al primului) devine infinit
{
costNod[i] = INF;
}
heap.push(make_pair(1, 0)); //punem nodul de plecare in heap
while(!heap.empty()) //cat timp heap-ul nu e gol
{
int nodActual = heap.top().first; //extragem nodul cel mai apropiat de graf
heap.pop(); //(adica cel care are muchia spre graf de cost minim)
if (!inArbore[nodActual]) //daca nu e deja in arbore
{
inArbore[nodActual] = true; //il punem in arbore
for (int i = 0; i < drum[nodActual].size(); i++) //ii parcurgem vecinii
{
int nodUrmator = drum[nodActual][i].first; //extragem vecinul
int cost = drum[nodActual][i].second;
if (!inArbore[nodUrmator]) //daca vecinul nu e in arbore
{
if (cost < costNod[nodUrmator]) //si noul cost (spre arbore) e mai mic decat cel vechi
{
heap.push(make_pair(nodUrmator, cost)); //il introducem in heap
costNod[nodUrmator] = cost; //ii memoram noul cost
tata[nodUrmator] = nodActual; //si ii actualizam tatal
}
}
}
}
}
}
void Afisare()
{
for (int i = 2; i <= n; i++)
{
costTotal += costNod[i]; //costul arborelui este suma costurilor muchiilor
}
fout << costTotal << '\n';
fout << n - 1 << '\n';
for (int i = 2; i <= n; i++) //folosim vectorul de tati pt a afisa muchiile din arbore
{
fout << i << ' ' << tata[i] << '\n';
}
}
int main()
{
Citire();
Prim();
Afisare();
return 0;
}