Cod sursa(job #1188639)

Utilizator SpiderManSimoiu Robert SpiderMan Data 20 mai 2014 03:06:53
Problema Arbore partial de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.73 kb
#define _CRT_SECURE_NO_WARNINGS
# include <algorithm>
# include <cstdio>
# include <set>
# include <vector>
using namespace std;

const char *FIN = "apm.in", *FOU = "apm.out";

struct muchie {
	int x, y, value;
	muchie() {
		x = y = value = 0;
	};
	muchie(int _x, int _y, int _value) {
		x = _x, y = _y, value = _value;
	};
};

/* operatorul de < pentru set */
inline bool operator < (muchie const& lhs, muchie const& rhs) {
	return (lhs.x < rhs.x) ||
		(lhs.x == rhs.x && lhs.y < rhs.y) ||
		(lhs.x == rhs.x && lhs.y == rhs.y && lhs.value < rhs.value);
}

inline bool operator == (muchie const& lhs, muchie const& rhs) {
	return lhs.x == rhs.x && lhs.y == rhs.y && lhs.value == rhs.value;
}

inline bool operator != (muchie const& lhs, muchie const& rhs) {
	return !(lhs == rhs);
}

int N, M, solution;
vector<muchie> U, T;

/* Parcurgem in adancime graful (X, T) si marcam in viz varfurile vizitate */
void dfs(int vf, vector<bool> &viz, vector<vector<bool>> &A) {
	viz[vf] = 1;
	for (int i = 1; i <= N; ++i)
		if (viz[i] == 0 && A[vf][i])
			dfs(i, viz, A);
}

void constructAdj(vector<vector<bool>> &A) {
    /* Construim matricea de adiacenta a grafului (X, T) */
	for (auto &u : T) {
		A[u.x][u.y] = A[u.y][u.x] = 1;
	}
}

muchie checkAndSolve() {
	vector<bool> viz(N + 1);
	vector<vector<bool>> A(N + 1, vector<bool>(N + 1));

	auto edge = *T.begin();
	constructAdj(A);
	dfs(edge.x, viz, A);

	for (int i = 1; i <= N; ++i) {
		/*  inseamna ca avem mai multe componente conexe, si fie
		A multimea formata din varfurile marcate din vectorul viz */
		if (viz[i] == false) {
			/* Pentru fiecare muchie din graful dat verificam daca apartine W(A)
			si luam minimul dintre toate acestea */
			muchie minEdge;
			for (auto &u : U) {
				int adj = viz[u.x] + viz[u.y];
				if (adj != 1) continue; // trebuie sa avem exact un capat in multimea A
				if (minEdge.x == 0 || (minEdge.x != 0 && minEdge.value > u.value))
					minEdge = u;
			}
			return minEdge;
		}
	}
	return muchie(-1, -1, -1); // daca avem doar 1 componenta conexa
}

int main(void) {
	freopen(FIN, "r", stdin);
	freopen(FOU, "w", stdout);

	scanf("%d %d", &N, &M);
	for (int i = 1, x, y, value; i <= M; ++i) {
		scanf("%d %d %d", &x, &y, &value);
		U.push_back(muchie(x, y, value));
		T.push_back(muchie(x, y, value));
	}

	for (auto &u : U) {
		T.erase(find(T.begin(), T.end(), u)); // T = T - {u}
		muchie result = checkAndSolve();
		if (result != muchie(-1, -1, -1)) {
			T.push_back(result); // T = T U {result}
		}
	}
	for (auto& u : T) { // calculam ponderea minima
		solution += u.value;
	}
	printf("%d\n%d\n", solution, N - 1);
	for (auto& u : T) { // afisam muchiile apm-ului
		printf("%d %d\n", u.x, u.y);
	}
}