Advertisement
Guest User

Untitled

a guest
Jan 19th, 2012
613
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.63 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <set>
  4. #include <map>
  5. #include <cstring>
  6. #include <cstdio>
  7. #include <cassert>
  8. #include <queue>
  9. #include <bitset>
  10. #include <cmath>
  11. #include <sstream>
  12. #include <string>
  13. #include <vector>
  14.  
  15. #define mp make_pair
  16. #define pb push_back
  17. #define sz(v) ((int)(v).size())
  18. #define all(v) (v).begin(),(v).end()
  19.  
  20. using namespace std;
  21.  
  22. typedef pair<int, int> ii;
  23. typedef long long int64;
  24. typedef vector<int> vi;
  25.  
  26. template<class T> T abs(T x) {return x > 0 ? x : (-x); }
  27. template<class T> T sqr(T x) {return x * x; }
  28.  
  29. typedef double D;
  30.  
  31. const D eps = 1E-10;
  32.  
  33. int sgn(D d) {
  34.     if (abs(d) < eps) return 0;
  35.     return d > 0 ? 1 : -1;
  36. }
  37.  
  38. struct P {
  39.     D x, y;
  40.     P(){}
  41.     P(D x, D y) : x(x), y(y) {}
  42.     D len() {
  43.         return sqrt(x * x + y * y);
  44.     }
  45.     P operator-(P p) {
  46.         return P(x - p.x, y - p.y);
  47.     }
  48.     D operator*(P p) {
  49.         return x * p.y - y * p.x;
  50.     }
  51.     D operator&(P p) {
  52.         return x * p.x + y * p.y;
  53.     }
  54. };
  55.  
  56. bool cross(P p1, P p2, P q1, P q2) {
  57.     return sgn((p1 - q1) * (q2 - q1)) * sgn((q2 - q1) * (p2 - q1)) > 0 &&
  58.         sgn((q1 - p1) * (p2 - p1)) * sgn((p2 - p1) * (q2 - p1)) > 0;
  59. }
  60.  
  61. D calc(vi &v, vector<P> &w) {
  62.     D res = 0;
  63.     for (int i = 0; i < sz(v); ++i) {
  64.         int j = (i + 1) % sz(v);
  65.         res += (w[v[i]] - w[v[j]]).len();
  66.     }
  67.     return res;
  68. }
  69.  
  70. void reverse(vi& v, int s, int t) {
  71.     while (1) {
  72.         if (s == t) break;
  73.         swap(v[s], v[t]);
  74.         s = (s + 1) % sz(v);
  75.         if (s == t) break;
  76.         t = (t - 1 + sz(v)) % sz(v);
  77.         if (s == t) break;
  78.     }
  79. }
  80.  
  81. vi S2opt(vi v, vector<P>& w) {
  82.     while (1) {
  83.         bool ch = false;
  84.         for (int i = 0; i < sz(v); ++i) {
  85.             for (int j = i + 2; j < sz(v); ++j) {
  86.                 int i0 = (i + 1) % sz(v);
  87.                 int j0 = (j + 1) % sz(v);
  88.                 if ((w[v[i]] - w[v[i0]]).len() + (w[v[j]] - w[v[j0]]).len() >
  89.                        (w[v[i]] - w[v[j]]).len() + (w[v[j0]] - w[v[i0]]).len() + eps) {
  90.                     ch = true;
  91.                     reverse(v, i0, j);
  92.                 }
  93.             }
  94.         }
  95.         if (!ch) break;
  96.     }
  97.     return v;
  98. }
  99.  
  100. /*
  101. vi S3opt(vi v, vector<P>& w) {
  102.     while (1) {
  103.         bool ch = false;
  104.     }
  105. }
  106. */
  107.  
  108. vi solve(vector<P> v, int ind) {
  109.     int cur = ind;
  110.     vi u(sz(v), 0);
  111.     u[cur] = 1;
  112.     vi res;
  113.     res.pb(cur);
  114.     int n = sz(v);
  115.     for (int i = 0; i < n - 1; ++i) {
  116.         int x = -1;
  117.         D y = 1E100;
  118.         vector<pair<D, int> > a;
  119.         vector<pair<D, int> > aa;
  120.  
  121.         for (int j = 0; j < n; ++j)
  122.             if (!u[j]) {
  123. /*                bool ok = true;
  124.                 for (int k = 0; k + 1 < sz(res); ++k)
  125.                     if (cross(v[cur], v[j], v[res[k]], v[res[k + 1]])) {
  126.                         ok = false;
  127.                         break;
  128.                     }
  129.                 if (ok) */
  130.                     a.pb(mp((v[cur] - v[j]).len(), j));
  131. /*                else
  132.                     aa.pb(mp((v[cur] - v[j]).len(), j));*/
  133.             }
  134.         if (!sz(a)) a = aa;
  135.         sort(all(a));
  136.         x = a[0].second;
  137.         double cx = 1;
  138.         for (int j = 0; j < sz(a); ++j) {
  139.             if (cx < 100000) cx *= 3.0;
  140.             int C = (int) cx + 1;
  141.             if (rand() % C == 0) {
  142.                 x = a[j].second;
  143.                 break;
  144.             }
  145.         }
  146.         res.pb(x);
  147.         cur = x;
  148.         u[cur] = true;
  149.     }
  150.     return res;
  151. }
  152.  
  153. vi solve(vector<P> v) {
  154.     vi res;
  155.     D val = 1E100;
  156.     for (int it = 0; it < 1000; ++it) {
  157.         for (int i = 0; i < sz(v); ++i) {
  158.             vi cur = solve(v, i);
  159.             cur = S2opt(cur, v);
  160.             if (calc(cur, v) < val) {
  161.                 val = calc(cur, v);
  162.                 res = cur;
  163.             }
  164.         }
  165.     }
  166.  
  167. /*    for (int it = 0; it < 1000; ++it) {
  168.         vi cur = res;
  169.         for (int i = 0; i < 10; ++i) {
  170.             int x = rand() % sz(v), y = rand() % sz(v);
  171.             if (x != y) reverse(cur, x, y);
  172.         }
  173.         cur = S2opt(cur, v);
  174.         if (calc(cur, v) < val) {
  175.             val = calc(cur, v);
  176.             res = cur;
  177.             cerr << val << "\n";
  178.         }
  179.     }*/
  180.  
  181. //    res = 3opt(res);
  182.  
  183.     return res;
  184. }
  185. /*
  186. vector<P> V;
  187. vi sol;
  188.  
  189. vi solve_brute(vector<P> v) {
  190.     V = v;
  191. }
  192. */
  193. int main()
  194. {
  195.     int n;
  196.     cin >> n;
  197.     vector<P> v(n);
  198.     for (int i = 0; i < n; ++i)
  199.         cin >> v[i].x >> v[i].y;
  200.  
  201.     vi res = solve(v);
  202.     cout << calc(res, v) << "\n";
  203.  
  204.     for (int i = 0; i < sz(res); ++i)
  205.         printf("%d ", res[i]);
  206.         return 0;
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement