Cod sursa(job #3243884)

Utilizator EricDimiericdc EricDimi Data 22 septembrie 2024 09:41:58
Problema Arbore partial de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
// Algoritmul lui Kruskal - O(n log n)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

ifstream f("apm.in");
ofstream g("apm.out");

const int MAX_N = 2e5, MAX_M = 4e5;

struct muchie
{
	int x, y;
	short cost;
} v[MAX_N + 1];

inline bool cmp(muchie a, muchie b)
{
	if (a.cost > b.cost)
		return 0;
	return 1;
}

class DSU
{
	private:
		int n;
		vector<int> t, card;
	public:
		// initializare
		void init(int NMAX)
		{
			n = NMAX;
			t.resize(n + 1);
			card.resize(n + 1);
			for (int i = 1; i <= n; i++)
			{
				t[i] = i;
				card[i] = 1;
			}
		}
		// radacina nodului x
		int Find(int x)
		{
			if (t[x] == x)
				return x;
			return t[x] = Find(t[x]);
		}
		// reuniunea a doua multimi
		void Union(int a, int b)
		{
			a = Find(a);
			b = Find(b);
			if (a == b)
				return;
			if (card[b] > card[a])
				swap(a, b);
			t[b] = a;
			card[a] += card[b];
		}
};

int n, m, k;
long long costMin;
vector<pair<int, int>> sol;

int main()
{
	f >> n >> m;

	for (int i = 0; i < m; i++)
		f >> v[i].x >> v[i].y >> v[i].cost;

	sort(v, v + m, cmp);

	DSU s;
	s.init(n);
	sol.reserve(n + 1);

	for (int i = 0; i < m; i++)
		if (s.Find(v[i].x) != s.Find(v[i].y))
		{
			xcostMin += v[i].cost;
			sol.push_back({v[i].x, v[i].y});
			//cout << v[i].x << ' ' << v[i].y << '\n';
			s.Union(v[i].x, v[i].y);
		}

	g << costMin << '\n' << n - 1 << '\n';

	for (int i = 0; i < n - 1; i++)
		g << sol[i].first << ' ' << sol[i].second << '\n';

	f.close();
	g.close();
	return 0;
}