Cod sursa(job #2860118)

Utilizator lucamLuca Mazilescu lucam Data 2 martie 2022 10:42:58
Problema Ciclu hamiltonian de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.63 kb
#include <bits/stdc++.h>

template<typename T>
using Vec = std::vector<T>;
template<typename T, typename U>
using Pair = std::pair<T, U>;
template<typename F>
using Func = std::function<F>;
using i64 = int64_t;
using u64 = uint64_t;
using i8 = char;
using u8 = unsigned char;
template<typename T>
T update_min(T &min, T val) {
	return min = std::min(min, val);
}
template<typename T>
T update_max(T &max, T val) {
	return max = std::max(max, val);
}
template<typename T>
using Lim = std::numeric_limits<T>;

std::ifstream in("hamilton.in");
std::ofstream out("hamilton.out");

const int N = 18;
const int Inf2 = 1 << 30;

int n;
int c[N][N], dp[1 << N][N];

namespace set {
	inline bool in(int set, int i) {
		return set & (1 << i);
	}

	inline int add(int set, int i) {
		return set | (1 << i);
	}
}

int main() {
	int m;
	in >> n >> m;
	for (int i = 0; i < n; ++i) {
		std::fill(c[i], c[i] + i, Inf2);
		std::fill(c[i] + 1, c[i] + n, Inf2);
	}
	for (int i = 0; i < 1 << n; ++i) {
		std::fill(dp[i], dp[i] + n, Inf2);
	}
	for (int i = 0; i < m; ++i) {
		int u, v, c;
		in >> u >> v >> c;
		::c[u][v] = c;
	}
	dp[1][0] = 0;
	for (int i = 1; i < 1 << n; i += 2) {
		for (int j = 0; j < n; ++j) {
			if (set::in(i, j)) {
				for (int k = 0; k < n; ++k) {
					if (!set::in(i, k) && !((c[j][k] | dp[i][j]) & Inf2)) {
						int i2 = set::add(i, k);
						dp[i2][k] = std::min(dp[i2][k], dp[i][j] + c[j][k]);
					}
				}
			}
		}
	}
	int cs = (1 << n) - 1;
	int ans = Inf2;
	for (int i = 1; i < n; ++i) {
		if (c[i][0] != Inf2) {
			ans = std::min(ans, dp[cs][i] + c[i][0]);
		}
	}
	if (ans == Inf2) {
		out << "Nu exista solutie\n";
	} else {
		out << ans << '\n';
	}
}