Advertisement
TAImatem

Решение "Обход Графа"

Jan 12th, 2023
720
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.60 KB | None | 1 0
  1. void Floyd_Warshall(int n, vector<vector<int>>& out_d)
  2. {
  3.     for (int k = 0; k < n; k++)
  4.         for (int i = 0; i < n; i++)
  5.             for (int j = 0; j < n; j++)
  6.                 if (out_d[i][k] < INT32_MAX && out_d[k][j] < INT32_MAX && out_d[i][j] > out_d[i][k] + out_d[k][j])
  7.                 {
  8.                     out_d[i][j] = out_d[i][k] + out_d[k][j];
  9.                 }
  10. }
  11.  
  12. int main() {
  13. #ifdef DEBUG
  14.     freopen("input.in", "r", stdin);
  15.     freopen("output.out", "w", stdout);
  16. #endif
  17.     int n, m;
  18.     int sum = 0;
  19.     cin >> n >> m;
  20.     vector<vector<int>> d(n, vector<int>(n, INT32_MAX));
  21.     vector<int> cnt(n, 0);
  22.     int u, v, w;
  23.     for (int i = 0; i < n; i++)
  24.         d[i][i] = 0;
  25.     while (m--)
  26.     {
  27.         cin >> u >> v >> w;
  28.         u--, v--;
  29.         d[u][v] = d[v][u] = min(d[v][u], w);
  30.         sum += w;
  31.         cnt[u]++;
  32.         cnt[v]++;
  33.     }
  34.     if (cnt[0] == 0 && sum != 0)
  35.     {
  36.         cout << -1 << endl;
  37.         return 0;
  38.     }
  39.  
  40.     Floyd_Warshall(n, d);
  41.     for (int i = 0; i < n - 1; i++)
  42.         for (int j = i + 1; j < n; j++)
  43.             if (d[i][j] == INT32_MAX && cnt[i] && cnt[j])
  44.             {
  45.                 cout << -1 << endl;
  46.                 return 0;
  47.             }
  48.  
  49.     vector<int> p_odd;
  50.     for (int i = 0; i < n; i++)
  51.         if (cnt[i] & 1)
  52.             p_odd.push_back(i);
  53.     vector<int> dp(1 << p_odd.size(), INT32_MAX);
  54.  
  55.     for (int i = 0; i + 1 < p_odd.size(); i++)
  56.         for (int j = i + 1; j < p_odd.size(); j++)
  57.             dp[(1 << i) + (1 << j)] = d[p_odd[i]][p_odd[j]];
  58.  
  59.     dp[0] = 0;
  60.     for (int a = 5; a < dp.size(); a++)
  61.     {
  62.         if ((__popcnt(a) & 1))
  63.             continue;
  64.  
  65.         int c = (a - 1) & a;
  66.         while (c)
  67.         {
  68.             if (!(__popcnt(c) & 1))
  69.             {
  70.                 int b = a ^ c;
  71.                 dp[a] = min(dp[a], dp[c] + dp[b]);
  72.             }
  73.             c = (c - 1) & a;
  74.         }
  75.     }
  76.     cout << sum + dp.back();//dp[dp.size()-1]
  77.     return 0;
  78. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement