Advertisement
maksincolf

задача о коммивояжёре с восстановлением ответа

May 20th, 2024
477
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.67 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const double INF = 1e9 + 7;     //бесконечность
  6.  
  7. double x[20], y[20];    //координаты городов.
  8.  
  9. //Заметим, что для N элементов существует 2^N возможных подмножеств (масок)
  10. //значением от 0 до 2^N - 1.
  11. //Можно просто возвести 2 в произвольную степень с помощью битового сдвига:
  12. //2^N = 1 << N
  13. double dp[1 << 20][20];
  14.  
  15. //Расстояние между городами a и b
  16. double dst(int a, int b) {
  17.     double dx = x[a] - x[b], dy = y[a] - y[b];
  18.     return sqrt(dx * dx + dy * dy);
  19. }
  20.  
  21. int main() {
  22.     int n;
  23.     cin >> n;
  24.  
  25.     for (int i = 0; i < n; i++) {
  26.         cin >> x[i] >> y[i];
  27.     }
  28.  
  29.     for (int mask = 0; mask < (1 << n); mask++) {
  30.         for (int i = 0; i < n; i++) {
  31.             dp[mask][i] = INF;
  32.         }
  33.     }
  34.  
  35.     dp[1][0] = 0;   //Маска 1 содержит только нулевой элемент.
  36.  
  37.     vector<int> pr (n + 1, -1); // массив предков
  38.  
  39.     for (int mask = 2; mask < (1 << n); mask++) {
  40.         for (int i = 0; i < n; i++) {
  41.             if ((mask >> i) & 1) {      //Если mask содержит i
  42.                 int mask_without_i = mask ^ (1 << i);
  43.  
  44.                 for (int j = 0; j < n; j++) {
  45.                     if (j != i && ((mask >> j) & 1)) {  //Если j != i и mask содержит j
  46.                         if (dp[mask][i] > dp[mask_without_i][j] + dst(j, i)) {
  47.                             // запоминаем
  48.                             dp[mask][i] = dp[mask_without_i][j] + dst(j, i);
  49.                             pr[i] = j;
  50.                         }
  51.                     }
  52.                 }
  53.             }
  54.         }
  55.     }
  56.  
  57.     double ans = INF;
  58.     int last_index = -1;
  59.     int mask_all = (1 << n) - 1;  //маска, содержащая все элементы
  60.  
  61.     for (int i = 0; i < n; i++) {
  62.         if (ans > dp[mask_all][i] + dst(i, 0)) {
  63.             ans = dp[mask_all][i] + dst(i, 0);
  64.             last_index = i;
  65.         }
  66.     }
  67.  
  68.     cout << ans << endl;
  69.     if (last_index != -1) {
  70.         // восстанавливаем путь
  71.         // путь выведется в обратном порядке, но нам это не важно, так как
  72.         // всё равно начинаем и заканчиваем и начинаем в одной и той же вершине (делаем круг)
  73.         int ind = last_index;
  74.         while (ind != -1) {
  75.             cout << ind << " ";
  76.             ind = pr[ind];
  77.         }
  78. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement