mr_dot_convict

216-Getting-in-line_UVa-mr.convict

Jun 25th, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.98 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include         <bits/stdc++.h>
  9. using namespace std;
  10. #pragma GCC      optimize ("Ofast")
  11. #pragma GCC      optimize ("unroll-loops")
  12. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  13.  
  14. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  15. #define PREC     cout.precision (2); cout << fixed
  16. #define bg(x)    " [ " << #x << " : " << (x) << " ] "
  17. #define x        first
  18. #define y        second
  19. using ll = long long;
  20. using ld = long double;
  21. using pii = pair<int,int>;
  22.  
  23. #define debug(args...) { \
  24.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  25.    stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); \
  26. }
  27. void err(istream_iterator<string> it) { it->empty();
  28.    cerr << " (Line : " << __LINE__ << ")" << '\n';
  29. }
  30. template<typename T, typename... Args>
  31. void err(istream_iterator<string> it, T a, Args... args) {
  32.    cerr << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  33.    err(++it, args...);
  34. }
  35. const int N = 10, infi = (int)1e9;
  36. const ld eps = 1e-9;
  37. vector <pii> point;
  38. int n;
  39. ld memo[N][1 << N], dp[N][1 << N];
  40. int par[N][1 << N];
  41.  
  42. inline ld dist(int s, int e) {
  43.    int sx, sy, ex, ey;
  44.    sx = point[s].x, sy = point[s].y;
  45.    ex = point[e].x, ey = point[e].y;
  46.    return hypot(sx-ex, sy-ey);
  47. }
  48. /*****************************BOTTOM UP SOLUTION starts*************************/
  49. void solve_bu_tsp(int tc) { // tsp bottom up solution
  50.    cout << "**********************************************************\n";
  51.    cout << "Network #" << tc << "\n";
  52.  
  53.    for (int mask = 0; mask < (1 << n); ++mask)
  54.       for (int i = 0; i < n; ++i)
  55.          dp[i][mask] = infi;
  56.  
  57.    for (int i = 0; i < n; ++i)
  58.       dp[i][1 << i] = 0, par[i][1 << i] = -1;
  59.  
  60.    for (int mask = 1; mask < (1 << n); ++mask) {
  61.       for (int pos = 0; pos < n; ++pos) {
  62.          if (!(mask & (1 << pos))) continue;
  63.          ld mn_val = (ld) infi;
  64.          for (int prv = 0; prv < n; ++prv) {
  65.             if (pos == prv || !(mask & (1 << prv)))
  66.                continue;
  67.             ld guess = dp[prv][mask-(1<<pos)] + dist(prv, pos);
  68.             if (mn_val > guess) {
  69.                mn_val = guess;
  70.                par[pos][mask] = prv;
  71.             }
  72.          }
  73.          dp[pos][mask] = min(dp[pos][mask], mn_val);
  74.       }
  75.    }
  76.  
  77.    ld mn_cycle = (ld) infi, total = 0;
  78.    int pos = -1, mask = (1 << n) - 1;
  79.    for (int i = 0; i < n; ++i) {
  80.       ld go = dp[i][mask];
  81.       if (mn_cycle > go) {
  82.          mn_cycle = go;
  83.          pos = i;
  84.       }
  85.    }
  86.  
  87.    vector <int> order = {pos};
  88.    while (pos != -1) {
  89.       order.push_back(par[pos][mask]);
  90.       int tmp = pos;
  91.       pos = par[pos][mask];
  92.       mask -= (1 << tmp);
  93.    }
  94.  
  95.    for (int i = 1; i < n; ++i) {
  96.       int sx, sy, ex, ey;
  97.       sx = point[order[i-1]].x, sy = point[order[i-1]].y;
  98.       ex = point[order[i]].x, ey = point[order[i]].y;
  99.       ld wt = dist(order[i-1], order[i]) + 16;
  100.       cout << "Cable requirement to connect (" << sx << "," << sy << ") to ("
  101.          << ex << "," << ey << ") is " << wt<< " feet.\n";
  102.       total += wt;
  103.    }
  104.    cout << "Number of feet of cable required is " << total << ".\n";
  105.    assert(fabs(total - mn_cycle - (n-1)*16) < eps);
  106. }
  107. /*****************************BOTTOM UP SOLUTION end *************************/
  108.  
  109. /*****************************TOP DOWN SOLUTION starts*************************/
  110. ld tsp (int pos, int mask) {
  111.    if (mask == (1 << n) - 1) return 0;
  112.    if (memo[pos][mask] > -1 + eps) return memo[pos][mask];
  113.  
  114.    ld mn_val = (ld) infi;
  115.    for(int nxt = 0; nxt < n; ++nxt) {
  116.       if (pos == nxt || (mask & (1 << nxt))) continue;
  117.       ld go = tsp(nxt, mask | (1 << nxt)) + dist(pos, nxt);
  118.  
  119.       if (mn_val > go + eps) {
  120.          mn_val = go;
  121.          par[pos][mask] = nxt;
  122.       }
  123.    }
  124.  
  125.    return memo[pos][mask] = mn_val;
  126. }
  127.  
  128. void solve_td_tsp(int tc) { // topdown O(n^2 * 2^n)
  129.    cout << "**********************************************************\n";
  130.    cout << "Network #" << tc << "\n";
  131.    for (int i = 0; i < n; ++i) for (int j = 0; j < (1 << n); ++j)
  132.       memo[i][j] = -1;
  133.  
  134.    ld mn_cycle = (ld) infi, total = 0;
  135.    int pos = -1;
  136.  
  137.    for (int i = 0; i < n; ++i) {
  138.       ld go = tsp(i, 1 << i);
  139.       if (mn_cycle > go) {
  140.          mn_cycle = go;
  141.          pos = i;
  142.       }
  143.    }
  144.    vector <int> order = {pos};
  145.    int mask = (1 << pos);
  146.    while (mask != (1 << n) - 1) {
  147.       order.push_back(par[pos][mask]);
  148.       pos = par[pos][mask];
  149.       mask |= (1 << pos);
  150.    }
  151.  
  152.    for (int i = 1; i < n; ++i) {
  153.       int sx, sy, ex, ey;
  154.       sx = point[order[i-1]].x, sy = point[order[i-1]].y;
  155.       ex = point[order[i]].x, ey = point[order[i]].y;
  156.       ld wt = dist(order[i-1], order[i]) + 16;
  157.       cout << "Cable requirement to connect (" << sx << "," << sy << ") to ("
  158.          << ex << "," << ey << ") is " << wt<< " feet.\n";
  159.       total += wt;
  160.    }
  161.    cout << "Number of feet of cable required is " << total << ".\n";
  162.    assert(fabs(total - mn_cycle - (n-1)*16) < eps);
  163. }
  164.  
  165. /*****************************TOP DOWN SOLUTION ends *************************/
  166.  
  167.  
  168.  
  169. /*****************************BRUTE FORCE SOLUTION starts *************************/
  170. void solve_bruteforce(int tc) { //O(n!)
  171.    cout << "**********************************************************\n";
  172.    cout << "Network #" << tc << "\n";
  173.    vector <int> perm, best;
  174.    for (int i = 0; i < n; ++i) perm.push_back(i);
  175.    best.assign(n, 0);
  176.  
  177.    ld mn_val = (ld)infi;
  178.  
  179.    do {
  180.       ld wt = 0;
  181.       for (int i = 1; i < n; ++i) {
  182.          wt += dist(perm[i-1], perm[i]);
  183.       }
  184.       if (mn_val > wt + eps) {
  185.          mn_val = wt;
  186.          for (int i = 0; i < n; ++i) best[i] = perm[i];
  187.       }
  188.    } while (next_permutation(perm.begin(), perm.end()));
  189.  
  190.    ld total = 0;
  191.    for (int i = 1; i < n; ++i) {
  192.       int sx, sy, ex, ey;
  193.       sx = point[best[i-1]].x, sy = point[best[i-1]].y;
  194.       ex = point[best[i]].x, ey = point[best[i]].y;
  195.       ld wt = dist(best[i-1], best[i]) + 16;
  196.       cout << "Cable requirement to connect (" << sx << "," << sy << ") to ("
  197.          << ex << "," << ey << ") is " << wt<< " feet.\n";
  198.       total += wt;
  199.    }
  200.    cout << "Number of feet of cable required is " << total << ".\n";
  201. }
  202.  
  203. /*****************************BRUTE FORCE SOLUTION starts *************************/
  204.  
  205. void read() {
  206.    point.assign(n, pii());
  207.    for (int i = 0; i < n; ++i) {
  208.       cin >> point[i].x >> point[i].y;
  209.    }
  210. }
  211.  
  212. signed main() {
  213.    IOS; PREC;
  214.    int tc = 1;
  215.    while (cin >> n, n) read(), solve_bu_tsp(tc++);
  216.    // while (cin >> n, n) read(), solve_td_tsp(tc++);
  217.    // while (cin >> n, n) read(), solve_bruteforce(tc++);
  218.  
  219.    return EXIT_SUCCESS;
  220. }
Add Comment
Please, Sign In to add comment