Pagini recente » Cod sursa (job #2716507) | Cod sursa (job #2116941) | Cod sursa (job #1038060) | Cod sursa (job #451469) | Cod sursa (job #588004)
Cod sursa(job #588004)
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
class DisjointSets{
struct Node{
int key;
int rang;
};
vector<Node> T;
public :
DisjointSets(){}
DisjointSets(size_t sz){
T.resize(sz);
for(int i = 0; i < sz; i++){
T[i].key = i;
T[i].rang = 1;
}
}
void insert(int);
int Find(int);
void Union(int,int);
int& operator[](int x){
return T[x].key;
}
};
struct edge{
int i,j,w;
edge(){}
bool operator == (const edge& e){
return e.w == this->w;
}
bool operator != (const edge& e){
return e.w != this->w;
}
friend bool operator < (const edge& e1, const edge& e2){
if(e1.w != e2.w)
return e1.w < e2.w;
else
return e1.j < e2.j;
}
friend bool operator > (const edge& e1, const edge& e2){
return e1.w > e2.w;
}
friend istream &operator >> (istream &is, edge& e)
{
is >> e.i;
is >> e.j;
is >> e.w;
return is;
}
friend ostream &operator << (ostream &os, const edge& e)
{
os << e.j << " " << e.i;
os << endl;
return os;
}
};
int cost = 0;
vector<edge> Kruskal(vector <edge>,int);
int main()
{
fstream in("apm.in",ios::in);
fstream out("apm.out",ios::out);
int n , m;
vector <edge> E;
in >> n >> m;
for(int i = 0; i < m; i++){
edge e;
in >> e;
E.push_back(e);
}
vector<edge> T = Kruskal(E,n);
vector<edge>::iterator it;
out << cost << endl;
out << T.size() << endl;
for(it = T.begin(); it != T.end(); ++it)
out << *it;
return EXIT_SUCCESS;
}
vector<edge> Kruskal(vector <edge> E, int n)
{
sort(E.begin(),E.end());
vector <edge> T;
vector <edge>::iterator it;
DisjointSets S(n);
for(it = E.begin(); it != E.end(); ++it){
int x = (*it).i-1;
int y = (*it).j-1;
if(S.Find(x) != S.Find(y)){
S.Union(S.Find(x),S.Find(y));
cost += (*it).w;
T.push_back(*it);
}
}
return T;
}
int DisjointSets::Find(int x)
{
int R, y;
//merg in sus pe arbore pana gasesc un nod care pointeaza catre el insusi
for (R = x; T[R].key != R; R = T[R].key);
//aplic compresia drumurilor
for (; T[x].key != x;)
{
y = T[x].key;
T[x].key = R;
x = y;
}
return R;
}
void DisjointSets::Union(int x, int y)
{
//unesc multimea cu rang mai mic de cea cu rang mai mare
if (T[x].rang > T[y].rang)
T[y].key = x;
else
T[x].key = y;
//in caz ca rangurile erau egale atunci cresc rangul noii multimi cu 1
if (T[x].rang == T[y].rang)
T[y].rang++;
}