Pagini recente » Cod sursa (job #1023408) | Cod sursa (job #1241173) | Borderou de evaluare (job #804544) | Cod sursa (job #2892946) | Cod sursa (job #1606385)
#include <iostream> // se aplica pe GRAF CONEX si NEORIENTAT
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue> //priorityQueue
using namespace std;
struct Muchie
{
int x, y, c;
friend bool operator>(const Muchie &a, const Muchie &b);
};
bool operator>(const Muchie &a,const Muchie &b)
{
return a.c > b.c;
}
priority_queue<Muchie, vector<Muchie>, greater<Muchie> > H; //min-heap
vector<int> h, T; //se folosesc pentru simularea arborelui
int N, M;
void citire();
int comp(Muchie i, Muchie j);
int Find(int x);
void Union(int x, int y);
void Kruskal();
int main()
{
citire();
Kruskal();
return 0;
}
void citire()
{
freopen("apm.in","rt",stdin);
freopen("apm.out","wt",stdout);
Muchie aux;
cin>>N>>M;
for(int i=0; i<M; ++i){
scanf("%d %d %d", &aux.x, &aux.y, &aux.c);
H.push(aux);
}
}
int Find(int x)
{
int rx = x, y;
while(rx != T[rx]) rx = T[rx];
while(x != rx) //Regula de compresie a drumului de la x la radacina sa
{
y = T[x];
T[x] = rx;
x = y;
}
return rx;
}
void Union(int x, int y)
{
if(h[x] > h[y])
T[y] = x;
else if(h[x] < h[y])
T[x] = y;
else{
h[x]++;
T[x] = y;
}
}
void Kruskal()
{
int cTotal=0, nrM=0, rx, ry, x, y; //numarul muchiilor selectate e 0
vector<pair<int, int> >S; //vectorul in care retinem muchiile arborelui solutie
for(int i=0; i<=N; ++i) //initial fiecare nod face parte dintr-un arbore separat
T.push_back(i);
h.assign(N+1, 1); //initial toate nodurile sunt pe primul nivel
while(nrM < N-1 && !H.empty())
{
x = H.top().x;
y = H.top().y;
rx = Find(x);
ry = Find(y);
if( rx != ry) //daca nu se formeaza ciclu
{
Union(x, y); //unificarea arborilor
nrM++; //creste numarul de muchii selectate
S.push_back(make_pair(x, y));
cTotal += H.top().c;
}
H.pop();
}
if(H.empty() && nrM < N-1){ //Daca am parcurs toate muchiile si inca nu am construit tot arborele
cout<<"Nu exista solutie\n";
return;
}
//afisare
cout<<cTotal<<'\n';
cout<<nrM<<'\n';
for(int i=0; i<N-1; ++i)
cout<<S[i].first<<' '<<S[i].second<<'\n';
}