Advertisement
erek1e

IOI '06 P4 - The Valley of Mexico

Jul 11th, 2023
555
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.07 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. #define bool char
  7.  
  8. int main() {
  9.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  10.     int n, m; cin >> n >> m;
  11.     vector<vector<bool>> connected(1+n, vector<bool>(1+n));
  12.     for (int i = 0; i < m; ++i) {
  13.         int u, v; cin >> u >> v;
  14.         connected[u][v] = connected[v][u] = true;
  15.     }
  16.  
  17.     auto previous = [&n](int i) {return i == 1 ? n : i-1;};
  18.     auto next = [&n](int i) {return i == n ? 1 : i+1;};
  19.  
  20.     vector<vector<vector<bool>>> dp(1+n, vector<vector<bool>>(1+n, vector<bool>(2))); // l, r, last
  21.     // last = 0 means last in the chain is left endpoint, 1 means last in the chain is right endpoint
  22.     // dp[l][r][last] = 0 if impossible, 1 if possible
  23.  
  24.     for (int i = 1; i <= n; ++i) dp[i][i][0] = true;
  25.  
  26.     for (int width = 1; width < n; ++width) {
  27.         for (int l = 1, r = width; l <= n; ++l, r = next(r)) {
  28.             // try move to l-1
  29.             int newL = previous(l);
  30.             if (connected[l][newL] && dp[l][r][0] || connected[r][newL] && dp[l][r][1]) dp[newL][r][0] = true;
  31.  
  32.             // try move to r+1
  33.             int newR = next(r);
  34.             if (connected[l][newR] && dp[l][r][0] || connected[r][newR] && dp[l][r][1]) dp[l][newR][1] = true;
  35.         }
  36.     }
  37.  
  38.     bool found = false;
  39.     for (int l = 1; l <= n; ++l) {
  40.         int r = previous(l);
  41.         if (dp[l][r][0] || dp[l][r][1]) {
  42.             found = true;
  43.             // reconstruct solution
  44.             int last = (dp[l][r][0] ? 0 : 1);
  45.             while (l != r) {
  46.                 if (last == 0) {
  47.                     cout << l << '\n';
  48.                     if (!connected[l][next(l)] || !dp[next(l)][r][0]) last = 1;
  49.                     l = next(l);
  50.                 } else {
  51.                     cout << r << '\n';
  52.                     if (!connected[r][previous(r)] || !dp[l][previous(r)][1]) last = 0;
  53.                     r = previous(r);
  54.                 }
  55.             }
  56.             cout << l << '\n';
  57.             break;
  58.         }
  59.     }
  60.     if (!found) cout << "-1\n";
  61.     return 0;
  62. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement