Cod sursa(job #1166611)

Utilizator ChallengeMurtaza Alexandru Challenge Data 3 aprilie 2014 18:31:54
Problema Arbore partial de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <fstream>
#include <vector>
#include <algorithm>

using namespace std;

const char InFile[] = "apm.in";
const char OutFile[] = "apm.out";
const int MaxN = 200111;

ifstream fin(InFile);
ofstream fout(OutFile);

struct Edge
{
	Edge(int x=0, int y=0, int cost=0) :x(x),y(y),cost(cost){}

	int x, y, cost;
};

struct Edge_CMP
{
	inline bool operator() (const Edge &A, const Edge &B)
	{
		return A.cost<B.cost;
	}
};

int N, M, x, y, cost, PMD[MaxN];
vector<Edge> E, sol;

inline void InitPMD()
{
	for (register int i = 1; i <= N; ++i)
	{
		PMD[i] = -1;
	}
}

inline int Root(const int &x)
{
	int root=x;
	while (PMD[root] > 0)
	{
		root = PMD[root];
	}
	int t = x;
	while (t != root)
	{
		int aux = PMD[t];
		PMD[t] = root;
		t = aux;
	}
	return root;
}

inline void Unify(const int &x, const int &y)
{
	int rx = Root(x);
	int ry = Root(y);
	if (rx == ry)
	{
		return;
	}
	if (PMD[rx] < PMD[ry])
	{
		PMD[rx] += PMD[ry];
		PMD[ry] = rx;
	}
	else
	{
		PMD[ry] += PMD[rx];
		PMD[rx] = ry;
	}
}

inline bool Unified(const int &x, const int &y)
{
	return Root(x) == Root(y);
}

int Kruskal()
{
	sort(E.begin(),E.end(),Edge_CMP());
	int cost = 0;
	InitPMD();
	for (vector<Edge>::iterator it = E.begin(); it != E.end(); ++it)
	{
		if (!Unified(it->x, it->y))
		{
			Unify(it->x,it->y);
			cost += it->cost;
			sol.push_back(*it);
		}
	}
	return cost;
}

int main()
{
	fin >> N >> M;
	for (register int i = 1; i <= M; ++i)
	{
		fin >> x >> y >> cost;
		E.push_back(Edge(x,y,cost));
	}
	fin.close();

	cost = Kruskal();

	fout << cost << "\n";
	fout << sol.size() << "\n";
	for (vector<Edge>::iterator it = sol.begin(); it != sol.end(); ++it)
	{
		fout << it->x << " " << it->y << "\n";
	}
	fout.close();
	return 0;
}