Vlad1000_nn

Untitled

Aug 16th, 2025
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.96 KB | None | 0 0
  1.  
  2. void calc_pathes(const vi& x, const vi& y, const vi& z, vi& mode, vvi& path)
  3. {
  4.     const int n = isz(mode);
  5.     const int m = isz(path);
  6.  
  7.     // Перебираю все пары путей из i в j
  8.     for (int i = 0; i < m; ++i) {
  9.         for (int j = i; j < m; ++j) {
  10.             if (i == j) continue;
  11.             // сколько нужно по модулю пройти расстояние
  12.             int total = abs(x[j] - x[i]) + abs(y[j] - y[i]) + abs(z[j] - z[i]);
  13.            
  14.             // Делаю bfs в 1мерном пространстве
  15.             queue<pair<int, int>> q; // шаги, текущая позиция (нам нужен total)
  16.  
  17.             q.push(make_pair(0, 0));
  18.             vi dist(total + 1, INF);
  19.             while (!q.empty()) {
  20.                 auto [step, curr] = q.front();
  21.                 q.pop();
  22.  
  23.                 if(curr > total) curr %= total; // иногда есть вариант перебежать и вернуться, поэтому берём по модулю
  24.                 if (dist[curr] <= step) continue;
  25.                 dist[curr] = step;
  26.  
  27.                 for (int k = 0; k < n; ++k)
  28.                     q.push(make_pair(step + 1, curr + mode[k]));
  29.             }
  30.             path[i][j] = path[j][i] = dist[total];
  31.         }
  32.     }
  33. }
  34.  
  35.  
  36. void solve()
  37. {    
  38.     int n, m; cin >> n >> m;
  39.     vi mode(n); cin >> mode;
  40.     vi x(m + 1), y(m + 1), z(m + 1); // создаю ещё фиктивную вершину в (0,0,0)
  41.     for (int i = 1; i <= m; ++i)
  42.         cin >> x[i] >> y[i] >> z[i];
  43.  
  44.     vvi path(m + 1, vi(m + 1, INF));
  45.     for (int i = 0; i <= m; ++i)
  46.         path[i][i] = 0;
  47.  
  48.     calc_pathes(x, y, z, mode, path);
  49.  
  50.     for (int i = 0; i <= m; ++i) {
  51.         for (int j = 0; j <= m; ++j)
  52.             if (path[i][j] == INF) { // Должен быть связным граф
  53.                 std::cout << -1 << '\n';
  54.                 return;
  55.             }
  56.     }
  57.     ++m;
  58.  
  59.     vvi dp(1 << m, vi(m, INF));
  60.     dp[1][0] = 0;
  61.  
  62.     for (int mask = 1; mask < (1 << m); ++mask) {
  63.  
  64.         // Т.к. стартуем в 0 вершине, то старт из других вершин отсекаем
  65.         int cnt{};
  66.         for (int i = 0; i < m; ++i)
  67.             cnt += get_bit(mask, i);
  68.         // когда маска вида 0..010..0
  69.         if (cnt == 1 && mask != 1) continue;
  70.  
  71.         for (int i = 0; i < m; ++i) {
  72.             for (int j = 0; j < m; ++j) {
  73.                 // i - где мы стоим, j - куда идём
  74.                 if (get_bit(mask, i) && i != j) {
  75.                     int total = dp[mask][i] + path[i][j];
  76.  
  77.                     if (total < dp[mask | (1 << j)][j])
  78.                         dp[mask | (1 << j)][j] = total;
  79.                 }
  80.             }
  81.         }
  82.     }
  83.  
  84.     int answ = INF;
  85.     for (int i = 1; i < m; ++i)
  86.         if (dp[(1 << m) - 1][i] < answ)
  87.             answ = dp[(1 << m) - 1][i];
  88.  
  89.     std::cout << answ << '\n';
  90. }
Advertisement
Add Comment
Please, Sign In to add comment