Advertisement
Guest User

Untitled

a guest
Oct 6th, 2013
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.67 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cassert>
  4. #include <ctime>
  5. #include <cstring>
  6. #include <cmath>
  7. #include <algorithm>
  8. #include <vector>
  9. #include <string>
  10. #include <queue>
  11. #include <set>
  12. #include <map>
  13.  
  14. using namespace std;
  15.  
  16. #define pb push_back
  17. #define mp make_pair
  18. #ifdef DEBUG
  19. #define eprintf(...) fprintf(stderr, __VA_ARGS__)
  20. #define TIMESTAMP(msg) eprintf("[ " #msg " ] Time=%.3lfs\n", clock() * 1.0 / CLOCKS_PER_SEC)
  21. #else
  22. #define eprintf(...)
  23. #define TIMESTAMP(msg)
  24. #endif
  25. #define sz(x) ((int)(x).size())
  26. #define TASKNAME "convexset"
  27.  
  28. typedef long long ll;
  29. typedef long double ld;
  30. typedef vector<ll> vll;
  31. typedef vector<int> vi;
  32. typedef vector<vi> vvi;
  33. typedef vector<bool> vb;
  34. typedef vector<vb> vvb;
  35. typedef pair<int, int> pii;
  36. typedef pair<ll, int> pli;
  37.  
  38. const int INF = 1e9;
  39. const int inf = INF;
  40. const double EPS = 1e-9;
  41. const double eps = EPS;
  42.  
  43. int sgn(int x) { return x < 0 ? -1 : !!x; }
  44. struct pt {
  45.   int x, y, id;
  46.   pt() : x(0), y(0), id(-1) {}
  47.   pt(int x, int y) : x(x), y(y), id(-1) {}
  48.   double dist() const { return sqrt(x * x + y * y); }
  49.  
  50.   pt operator-(const pt &p2) const { return pt(x - p2.x, y - p2.y); }
  51.   int operator*(const pt &p2) const { return sgn(x * p2.y - y * p2.x); }
  52.   bool operator<(const pt &p2) const { return y != p2.y ? y < p2.y : x < p2.x; }
  53. };
  54.  
  55. bool rcmp(const pt &a, const pt &b) {
  56.   return a * b > 0;
  57. }
  58.  
  59. bool isang(const pt &b, const pt &c, const pt &p) {
  60.   return b * p > 0 && p * c > 0;
  61. }
  62.  
  63. bool check_inside(pt a, pt b, pt c, pt p) {
  64.   b = b - a; c = c - a; p = p - a; a = pt();
  65.   if (b * c < 0) swap(b, c);
  66.   assert(b * c > 0);
  67.  
  68.   if (!isang(b, c, p)) return false;
  69.   if (!isang(c - b, pt() - b, p - b)) return false;
  70.   return true;
  71. }
  72.  
  73. const int MAXN = 60;
  74. vi inside[MAXN][MAXN][MAXN];
  75. const vi& getIn(int a, int b, int c) {
  76.   if (a > b) swap(a, b);
  77.   if (b > c) swap(b, c);
  78.   if (a > b) swap(a, b);
  79.   return inside[a][b][c];
  80. }
  81.  
  82. double dist[MAXN][MAXN];
  83. int k;
  84.  
  85. pair<double, int> dyn[MAXN + 1][MAXN + 2];
  86. pair<double, vi> solve(vector<pt> &pts) {
  87.   int n = sz(pts);
  88.   pts.pb(pts[0]);
  89.  
  90.   for (int i = 0; i <= n; i++)
  91.   for (int j = 0; j <= n + 1; j++)
  92.     dyn[i][j] = mp(1e100, -1);
  93.  
  94.   dyn[0][0] = mp(0, -1);
  95.  
  96.   for (int pr = 0; pr < n; pr++)
  97.   for (int pcnt = 0; pcnt <= n; pcnt++) if (dyn[pr][pcnt].first < 1e99) {
  98.     double cur = dyn[pr][pcnt].first;
  99.  
  100.     for (int ne = pr + 1; ne <= n; ne++) {
  101.       int ncnt = pcnt + 1 + sz(getIn(pts[0].id, pts[pr].id, pts[ne].id));
  102.       assert(ncnt <= n);
  103.       dyn[ne][ncnt] = min(dyn[ne][ncnt], mp(cur + dist[pts[pr].id][pts[ne].id], pr));
  104.     }
  105.   }
  106.  
  107.   double bres = dyn[n][k].first;
  108.   for (int i = k + 1; i <= n; i++)
  109.     assert(dyn[n][i].first >= bres - eps);
  110.  
  111.   vi res;
  112.   int pcnt = k;
  113.   for (int ne = n; ne > 0;) {
  114.     int pr = dyn[ne][pcnt].second;
  115.     assert(pr >= 0);
  116.  
  117.     const vi &in = getIn(pts[0].id, pts[pr].id, pts[ne].id);
  118.     pcnt -= 1 + sz(in);
  119.     res.insert(res.end(), in.begin(), in.end());
  120.     res.pb(pts[ne].id);
  121.    
  122.     ne = pr;
  123.   }
  124.   assert(pcnt == 0);
  125. //  eprintf("%d == %d\n", sz(res), k);
  126.   assert(sz(res) == k);
  127.   return mp(bres, res);
  128. }
  129.  
  130. int main() {
  131.   freopen(TASKNAME ".in", "r", stdin);
  132.   freopen(TASKNAME ".out", "w", stdout);
  133.  
  134.   int n;
  135.   while (scanf("%d%d", &n, &k) == 2) {
  136.     vector<pt> pts(n);
  137.     for (int i = 0; i < n; i++)
  138.       scanf("%d%d", &pts[i].x, &pts[i].y), pts[i].id = i;
  139.  
  140.     for (int i = 0; i < n; i++)
  141.     for (int j = 0; j < n; j++)
  142.       dist[i][j] = (pts[i] - pts[j]).dist();
  143.  
  144.     for (int i = 0; i < n; i++)
  145.     for (int j = i + 1; j < n; j++)
  146.     for (int k = j + 1; k < n; k++) {
  147.       for (int x = 0; x < n; x++) if (x != i && x != j && x != k && check_inside(pts[i], pts[j], pts[k], pts[x])) {
  148.         inside[i][j][k].pb(x);
  149.       }
  150.     }
  151.  
  152.     pair<double, vi> bans;
  153.     bans.first = 1e100;
  154.     for (int bot = 0; bot < n; bot++) {
  155.       vector<pt> rem;
  156.       for (int i = 0; i < n; i++)
  157.         if (pts[bot] < pts[i]) {
  158.           pt res = pts[i] - pts[bot];
  159.           assert(pt() < res);
  160.           res.id = i;
  161.           rem.pb(res);
  162.         }
  163.       sort(rem.begin(), rem.end(), rcmp);
  164.       pt root; root.id = bot;
  165.       rem.insert(rem.begin(), root);
  166.  
  167.       if (sz(rem) >= k) {
  168.         pair<double, vi> cans = solve(rem);
  169.         bans = min(bans, cans);
  170.       }
  171.     }
  172.     assert(sz(bans.second) == k);
  173.     printf("%.18lf\n", bans.first);
  174.     for (int i = 0; i < sz(bans.second); i++)
  175.       printf("%d%c", bans.second[i] + 1, "\n "[i + 1 < sz(bans.second)]);
  176.  
  177.     for (int i = 0; i < n; i++)
  178.     for (int j = i + 1; j < n; j++)
  179.     for (int k = j + 1; k < n; k++)
  180.       inside[i][j][k].clear();
  181.   }
  182.   TIMESTAMP(end);
  183.   return 0;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement