Advertisement
Dang_Quan_10_Tin

TAXi

Dec 2nd, 2020
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <algorithm>
  5. #include <vector>
  6. #define bit(i, x) (((x) >> (i)) & 1)
  7. #define task "taxi"
  8. using namespace std;
  9. using ll = long long;
  10. using ld = long double;
  11.  
  12. const int N = 21 + 2;
  13. int n, m, trace[1 << 21][21];
  14. int d[N][N], par[N][N], a[N][N];
  15. bool flag;
  16. ll dp[1 << 21][21];
  17. vector<int> res;
  18. const ll Inf = 1e17;
  19.  
  20. void Read()
  21. {
  22.     cin >> n;
  23.     m = 2 * n + 1;
  24.     for (int i = 0; i < m; ++i)
  25.         for (int j = 0; j < m; ++j)
  26.             cin >> d[i][j],
  27.                 a[i][j] = d[i][j];
  28. }
  29.  
  30. void Dijkstra(int x, int a[], int par[])
  31. {
  32.     struct Tque
  33.     {
  34.         int v;
  35.         int w;
  36.         Tque() {}
  37.         Tque(int v, int w)
  38.         {
  39.             this->v = v;
  40.             this->w = w;
  41.         }
  42.         bool Valid(int a[])
  43.         {
  44.             return w == a[v];
  45.         }
  46.         bool operator<(const Tque &a) const
  47.         {
  48.             return w > a.w;
  49.         }
  50.     };
  51.     priority_queue<Tque> s;
  52.     s.push(Tque(x, 0));
  53.     a[x] = 0;
  54.     while (s.size())
  55.     {
  56.         Tque c = s.top();
  57.         s.pop();
  58.         if (!c.Valid(a))
  59.             continue;
  60.         for (int i = 0; i < m; ++i)
  61.         {
  62.             if (a[i] > a[c.v] + d[c.v][i])
  63.             {
  64.                 a[i] = a[c.v] + d[c.v][i];
  65.                 par[i] = c.v;
  66.                 s.push(Tque(i, a[i]));
  67.             }
  68.         }
  69.     }
  70. }
  71.  
  72. void Floyd()
  73. {
  74.     fill_n(&a[0][0], N * N, Inf);
  75.     for (int i = 0; i < m; ++i)
  76.         Dijkstra(i, a[i], par[i]);
  77. }
  78.  
  79. void Shortest_path(int i, int j)
  80. {
  81.     if (i == j)
  82.         return;
  83.     Shortest_path(i, par[i][j]);
  84.     res.push_back(j);
  85. }
  86.  
  87. void Trace(int i, int j)
  88. {
  89.     if (i == 0)
  90.         return;
  91.     Trace(i ^ (1 << j), trace[i][j]);
  92.     res.push_back(trace[i][j]);
  93.     Shortest_path(trace[i][j], j);
  94.     res.push_back(j);
  95. }
  96.  
  97. void Solve()
  98. {
  99.     fill_n(&dp[0][0], (1 << 21) * 21, Inf);
  100.     dp[1][0] = 0;
  101.     for (int i = 1; i < (1 << m); ++i)
  102.     {
  103.         flag = 0;
  104.         for (int j = 1; j <= n; ++j)
  105.             if (bit(j + n, i) && (!bit(j, i)))
  106.             {
  107.                 flag = 1;
  108.                 break;
  109.             }
  110.         if (flag)
  111.             continue;
  112.         for (int j = 0; j < m; ++j)
  113.             if (bit(j, i))
  114.                 for (int t = 0; t < m; ++t)
  115.                     if (t != j && bit(t, i))
  116.                     {
  117.                         if (dp[i][j] > dp[i ^ (1 << j)][t] + a[t][j])
  118.                         {
  119.                             dp[i][j] = dp[i ^ (1 << j)][t] + a[t][j];
  120.                             trace[i][j] = t;
  121.                         }
  122.                     }
  123.     }
  124.     ll ans = Inf;
  125.     int v;
  126.     for (int i = 0; i < m; ++i)
  127.         if (ans > dp[(1 << m) - 1][i] + a[i][0])
  128.         {
  129.             ans = dp[(1 << m) - 1][i] + a[i][0];
  130.             v = i;
  131.         }
  132.     cout << ans << "\n";
  133.     Trace((1 << m) - 1, v);
  134.     Shortest_path(v, 0);
  135.     res.resize(unique(res.begin(), res.end()) - res.begin());
  136.     cout << res.size() << "\n";
  137.     for (auto i : res)
  138.         cout << i << " ";
  139. }
  140.  
  141. int32_t main()
  142. {
  143.     ios_base::sync_with_stdio(0);
  144.     cin.tie(0);
  145.     cout.tie(0);
  146.     if (fopen(task ".INP", "r"))
  147.     {
  148.         freopen(task ".INP", "r", stdin);
  149.         freopen(task ".OUT", "w", stdout);
  150.     }
  151.     Read();
  152.     Floyd();
  153.     Solve();
  154. }
  155.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement