Advertisement
SorahISA

TIOJ 1928

Feb 28th, 2020
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.97 KB | None | 0 0
  1. /* TIOJ 1928 --- AC code by SorahISA */
  2. /* https://tioj.ck.tp.edu.tw/problems/1928 */
  3.  
  4. #pragma GCC target("avx2")
  5. #pragma GCC optimize("O3", "unroll-loops")
  6.  
  7. #include <bits/stdc++.h>
  8. using namespace std;
  9.  
  10. #define int long long
  11. #define double long double
  12.  
  13. #define X first
  14. #define Y second
  15.  
  16. #define fastIO() ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
  17. #define RANDOM() random_device __rd; \
  18.                  mt19937 __gen = mt19937(__rd()); \
  19.                  uniform_int_distribution<int> __dis(0, MAXN); \
  20.                  auto rnd = bind(__dis, __gen);
  21.  
  22. const int MAXN = 1E6;
  23. const int maxn = 800 + 5;
  24.  
  25. pair<pair<int, int>, int> v[maxn];
  26. double dp[maxn][maxn];
  27. int fr[maxn][maxn];
  28.  
  29. double Dis(pair<int, int> a, pair<int, int> b) {
  30.     return sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y));
  31. }
  32.  
  33. double Polar(pair<double, double> a, pair<int, int> b) {
  34.     double tX = b.X, tY = b.Y;
  35.     tX -= a.X, tY -= a.Y;
  36.     // cerr << "Polar(" << b.X << ", " << b.Y << "): " << tY << "/" << tX << ": " << tY / tX << "\n";
  37.     return tY / tX;
  38. }
  39.  
  40. int Upper(pair<double, double> a, pair<int, int> b) {
  41.     double tX = b.X, tY = b.Y;
  42.     tX -= a.X, tY -= a.Y;
  43.     return tY > 0;
  44. }
  45.  
  46. void PrintAnswer(int L, int R) {
  47.     if (L + 2 >= R) return;
  48.    
  49.     if (L + 1 < fr[L][R]) cout << v[L].Y << " " << v[fr[L][R]].Y << "\n";
  50.     if (fr[L][R] + 1 < R) cout << v[fr[L][R]].Y << " " << v[R].Y << "\n";
  51.     PrintAnswer(L, fr[L][R]);
  52.     PrintAnswer(fr[L][R], R);
  53. }
  54.  
  55. int32_t main() {
  56.     fastIO();
  57.    
  58.     int n, tok = 0;
  59.     double sX = 1e-6, sY = 1e-6;
  60.     cin >> n;
  61.    
  62.     /// sort by Polar ///
  63.     for (int i = 0; i < n; ++i) cin >> v[i].X.X >> v[i].X.Y, v[i].Y = tok++, sX += v[i].X.X, sY += v[i].X.Y;
  64.     // cerr << "center(" << sX / n << ", " << sY / n << ")\n";
  65.     sort(v, v + n, [&](auto a, auto b) {
  66.         if (Upper({sX / n, sY / n}, a.X) != Upper({sX / n, sY / n}, b.X)) {
  67.             return Upper({sX / n, sY / n}, a.X) == 1;
  68.         }
  69.         double scA = Polar({sX / n, sY / n}, a.X);
  70.         double scB = Polar({sX / n, sY / n}, b.X);
  71.         if ((scA > 0 and scB > 0) or (scA < 0 and scB < 0)) {
  72.             return scA < scB;
  73.         }
  74.         return scA > scB;
  75.     });
  76.    
  77.     /// dp and backtracking --- dp[i][j] = min(dp[i][k] + dp[k][j] + Dis(v[i], v[k])) ///
  78.     for (int len = 4; len <= n; ++len) {
  79.         for (int i = 0; i < n-len+1; ++i) {
  80.             int j = i + len - 1;
  81.             dp[i][j] = 1E12;
  82.             fr[i][j] = j;
  83.            
  84.             /// connection from v[i] ///
  85.             for (int k = i+2; k <= j; ++k) {
  86.                 if (dp[i][k] + dp[k][j] + Dis(v[i].X, v[k].X) + (k + 1 >= j ? 0 : Dis(v[k].X, v[j].X)) < dp[i][j]) {
  87.                     dp[i][j] = dp[i][k] + dp[k][j] + Dis(v[i].X, v[k].X) + (k + 1 == j ? 0 : Dis(v[k].X, v[j].X));
  88.                     fr[i][j] = k;
  89.                 }
  90.             }
  91.            
  92.             /// connection from v[j] ///
  93.             if (dp[i + 1][j] + Dis(v[i + 1].X, v[j].X) < dp[i][j]) {
  94.                 dp[i][j] = dp[i + 1][j] + Dis(v[i + 1].X, v[j].X);
  95.                 fr[i][j] = i + 1;
  96.             }
  97.            
  98.             /// Doing dp from both side cause TLE ///
  99.             /*
  100.             for (int k = j-2; k >= i; --k) {
  101.                 if (dp[i][k] + dp[k][j] + Dis(v[k].X, v[j].X) + (k - 1 <= i ? 0 : Dis(v[i].X, v[k].X)) < dp[i][j]) {
  102.                     dp[i][j] = dp[i][k] + dp[k][j] + Dis(v[k].X, v[j].X) + (k - 1 <= i ? 0 : Dis(v[i].X, v[k].X));
  103.                     fr[i][j] = k;
  104.                 }
  105.             }
  106.             */
  107.         }
  108.     }
  109.    
  110.     /*
  111.     cout << fixed << setprecision(10);
  112.    
  113.     for (int i = 0; i < n; ++i) cerr << v[i].X.X << " " << v[i].X.Y << ": " << v[i].Y << "\n";
  114.    
  115.     for (int i = 0; i < n; ++i) {
  116.         for (int j = 0; j < n; ++j) {
  117.             cerr << dp[i][j] << "\t\n"[j == n-1];
  118.         }
  119.     }
  120.     */
  121.    
  122.     /// Recurse to print answer ///
  123.     PrintAnswer(0, n - 1);
  124.    
  125.     return 0;
  126. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement