Pagini recente » Cod sursa (job #1727101) | Cod sursa (job #1671066) | Cod sursa (job #1873425) | Cod sursa (job #253641) | Cod sursa (job #3271469)
#include <iostream>
#include <fstream>
#include <vector>
bool citire(std::vector<std::vector<int> > &graf, std::vector<std::vector<int> > &costGraf, int &n) {
int m;
int i, j, w;
std::ifstream f("hamilton.in");
f >> n >> m;
graf.resize(n);
costGraf.resize(n, std::vector<int>(n, 1e9 + 1));
std::vector<int> grad(n);
// TEOREMA LUI DIRAC: Intr-un graf cu n>=3 noduri, fiecare nod are grad(v)>=n/2 <=> graf hamiltonian.
while (m--) {
f >> i >> j >> w;
graf[i].push_back(j);
costGraf[i][j] = w;
++grad[j];
}
f.close();
// verificam Teorema lui Dirac
if (n >= 3)
for (i = 0; i < n; ++i)
if (grad[i] < n / 2)
return false;
return true;
}
void sol() {
std::vector<std::vector<int> > graf;
std::vector<std::vector<int> > costGraf;
int n;
if (!citire(graf, costGraf, n)) {
std::ofstream g("hamilton.out");
g << "Nu exista solutie";
g.close();
return;
}
const int nrSubmultimi = 1 << n;
std::vector costLant(n, std::vector<int>(nrSubmultimi, 1e9 + 1));
costLant[0][1] = 0;
// c[k][S] = costul minim al unui lant care incepe in nodul 0, se termina in nodul k si are nodurile intermediare
// din multimea S (sir binar codificat de un numar).
// c[0][1] = 0;
for (int S = 0; S < nrSubmultimi; ++S)
// pentru fiecare submultime posibila de varfuri din lant
for (int i = 0; i < n; ++i)
// pentru fiecare nod din graf
if (S & (1 << i))
// daca nodul i face parte din multimea de noduri (daca nu face, cum putem avea lant de la 0 la i?)
for (const auto &j: graf[i])
if (!(S & (1 << j))) {
// daca vecinul j al lui i nu face parte din submultime
const int aux = S | (1 << j); // il bagam pe j in submultime (intr-o variabila auxiliara)
costLant[j][aux] = std::min(costLant[j][aux], costLant[i][S] + costGraf[i][j]);
}
// am calculat doar lanturile
// costul total al unui ciclu hamiltonian va fi lantul de la 0 la i (cu toate nodurile grafului) + costGraf[i][0]
int costMin = 1e9 + 1;
for (int i = 0; i < n; ++i)
if (costGraf[i][0] != 1e9 + 1)
costMin = std::min(costMin, costLant[i][nrSubmultimi - 1] + costGraf[i][0]);
std::ofstream g("hamilton.out");
if (costMin == 1e9 + 1)
g << "Nu exista solutie";
else
g << costMin;
g.close();
}
int main() {
sol();
return 0;
}