davidbejenariu2

tsp

Apr 27th, 2022
1,086
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.68 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4.  
  5. using namespace std;
  6.  
  7. typedef pair<long long, long long> pll;
  8.  
  9. long long getOrientation(pll &a, pll &b, pll &c) {
  10.     return a.first * b.second + b.first * c.second + c.first * a.second - c.first * b.second - b.first * a.second - a.first * c.second;
  11. }
  12.  
  13. vector<pll> getConvexHull(vector<pll> &points) {
  14.     vector<pll> hull;
  15.     int leftmost = 0;
  16.     int n = int(points.size());
  17.  
  18.     for (int i = 1; i < n; ++i) {
  19.         if (points[i].first < points[leftmost].first) {
  20.             leftmost = i;
  21.         }
  22.     }
  23.  
  24.     int current = leftmost, s;
  25.  
  26.     do {
  27.         hull.push_back(points[current]);
  28.         s = (current + 1) % n;
  29.  
  30.         for (int i = 0; i < n; ++i) {
  31.             if (getOrientation(points[current], points[s], points[i]) < 0) {
  32.                 s = i;
  33.             }
  34.         }
  35.  
  36.         current = s;
  37.     } while (current != leftmost);
  38.  
  39.     return hull;
  40. }
  41.  
  42. double distance(pll &a, pll &b) {
  43.     return sqrt((b.first - a.first) * (b.first - a.first) + (b.second - a.second) * (b.second - a.second));
  44. }
  45.  
  46. bool findPoint(pll &point, vector<pll> &hull) {
  47.     for (auto &p : hull) {
  48.         if (point == p) {
  49.             return true;
  50.         }
  51.     }
  52.  
  53.     return false;
  54. }
  55.  
  56. double getDistance1(pll &i, pll &j, pll &r) {
  57.     return distance(i, r) + distance(r, j) - distance(i, j);
  58. }
  59.  
  60. double getDistance2(pll &i, pll &j, pll &r) {
  61.     return (distance(i, r) + distance(r, j)) / distance(i, j);
  62. }
  63.  
  64. pair<pll, pll> findClosest(pll &r, vector<pll> &hull) {
  65.     double minDist = 1 << 30;
  66.     pair<pll, pll> ans;
  67.  
  68.     for (auto i = 1; i < hull.size(); ++i) {
  69.         double dist = getDistance1(hull[i - 1], hull[i], r);
  70.  
  71.         if (dist < minDist) {
  72.             minDist = dist;
  73.             ans = {hull[i - 1], hull[i]};
  74.         }
  75.     }
  76.  
  77.     double dist = getDistance1(hull[hull.size() - 1], hull[0], r);
  78.  
  79.     if (dist < minDist) {
  80.         minDist = dist;
  81.         ans = {hull[hull.size() - 1], hull[0]};
  82.     }
  83.  
  84.     return ans;
  85. }
  86.  
  87. int main() {
  88.     int n, x, y;
  89.     vector<pll> points;
  90.  
  91.     cin >> n;
  92.  
  93.     for (int i = 1; i <= n; ++i) {
  94.         cin >> x >> y;
  95.         points.emplace_back(x, y);
  96.     }
  97.  
  98.     bool inHull[n];
  99.     auto hull = getConvexHull(points);
  100.  
  101.     for (auto i = 0; i < points.size(); ++i) {
  102.         if (findPoint(points[i], hull)) {
  103.             inHull[i] = true;
  104.         }
  105.     }
  106.  
  107.     int count = int(points.size() - hull.size());
  108.  
  109.     while (count) {
  110.         vector<pair<pair<pll, pll>, int>> candidates;
  111.  
  112.         for (auto i = 0; i < points.size(); ++i) {
  113.             if (!inHull[i]) {
  114.                 auto p = findClosest(points[i], hull);
  115.                 candidates.emplace_back(p, i);
  116.             }
  117.         }
  118.  
  119.         double minDist = 1 << 30;
  120.         pair<pair<pll, pll>, int> bestCandidate;
  121.  
  122.         for (auto &c : candidates) {
  123.             auto dist = getDistance2(c.first.first, c.first.second, points[c.second]);
  124.  
  125.             if (dist < minDist) {
  126.                 minDist = dist;
  127.                 bestCandidate = c;
  128.             }
  129.         }
  130.  
  131.         hull.push_back(points[bestCandidate.second]);
  132.         inHull[bestCandidate.second] = true;
  133.         --count;
  134.  
  135.         for (auto i = 0; i < hull.size() - 2; ++i) {
  136.             if (hull[i] == bestCandidate.first.first) {
  137.                 for (auto j = hull.size() - 1; j > i; --j) {
  138.                     hull[j] = hull[j - 1];
  139.                 }
  140.  
  141.                 hull[i + 1] = points[bestCandidate.second];
  142.                 break;
  143.             }
  144.         }
  145.     }
  146.  
  147.     hull.push_back(hull.front());
  148.  
  149.     for (auto &p : hull) {
  150.         cout << p.first << ' ' << p.second << '\n';
  151.     }
  152.  
  153.     return 0;
  154. }
Advertisement
Add Comment
Please, Sign In to add comment