Cod sursa(job #2712460)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 25 februarie 2021 19:39:29
Problema Ciclu hamiltonian de cost minim Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
// dp[i][j] = costul minim daca am ajuns in nodul i si am trecut prin toate
// nodurile din j j o sa fie o submultime de noduri
//
// dp[n][{1,2..,n}] -> solutie
//
// dp[0][{0}] = 0
// dp[1][{0,1}] = 9
// dp[4][{0,1,4}] = 12
//
//
// {0,1,4} = 10011
//
// dp[i][mask] = costul minim daca am ajuns in nodul i si am trecut prin toate
// nodurile din masca j (j este reprezentarea binara a starii nodurilor prin
// care am trecut)
//
// suntem in starea dp[i][mask]
// exista muchie de la j la i cu cost c
// dp[i][mask] = min(dp[j][mask - (2^i)] + c), pt orice j astfel incat sa existe
// muchie de la j la i

#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

const int kMaxN = 18;
const int kInf = 1 << 29;

vector<pair<int, int>> v[kMaxN];
int dp[kMaxN][1 << kMaxN];

int main() {
  ifstream cin("hamilton.in");
  ofstream cout("hamilton.out");

  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int x, y, c;
    cin >> x >> y >> c;
    v[y].push_back({x, c});
  }

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < (1 << n); j++) {
      dp[i][j] = kInf;
    }
  }

  dp[0][1] = 0;
  for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 1; i < n; i++) {
      if ((1 << i) & mask) {
        for (auto p : v[i]) {
          int j = p.first;
          int c = p.second;
          dp[i][mask] = min(dp[i][mask], dp[j][mask - (1 << i)] + c);
        }
      }
    }
  }

  int ans = kInf;
  for (auto p : v[0]) {
    int j = p.first;
    int c = p.second;
    ans = min(ans, dp[j][(1 << n) - 1] + c);
  }

  if (ans == kInf)
    cout << "Nu exista solutie";
  else
    cout << ans;

  return 0;
}