Advertisement
Guest User

Untitled

a guest
Dec 11th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.51 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <random>
  3.  
  4. using namespace std;
  5.  
  6. typedef unsigned long long ull;
  7. typedef long long ll;
  8. typedef long double ld;
  9. //#define int ll
  10. typedef pair<int, int> pii;
  11. typedef pair<pii, pii> piii;
  12. typedef pair<ll, ll> pll;
  13. typedef vector<int> vi;
  14. typedef vector<pii> vpi;
  15. typedef vector< vi > vvi;
  16. typedef vector< vvi > vvvi;
  17. typedef vector<short> vs;
  18. typedef vector<vs> vvs;
  19. typedef vector<vvs> vvvs;
  20. typedef vector<ll> vl;
  21. typedef vector<vl> vvl;
  22. typedef vector<vvl> vvvl;
  23. typedef vector<ld> vld;
  24. typedef vector<vld> vvld;
  25. typedef vector<vvld> vvvld;
  26. typedef vector<string> vst;
  27. typedef vector<vst> vvst;
  28. typedef pair<ld, ld> pld;
  29. typedef complex<double> base;
  30.  
  31. #define inmin(a, b) a = min(a, (b))
  32. #define inmax(a, b) a = max(a, (b))
  33. #define mp(a, b) make_pair((a), (b))
  34. #define ALL(a) a.begin(),a.end()
  35. #define RALL(a) a.rbegin(),a.rend()
  36. #define sqr(x) ((x) * (x))
  37. #define fori(i, n) for(int i = 0; i < int(n); ++i)
  38. #define SZ(a) ((int)((a).size()))
  39. #define triple(T) tuple<T, T, T>
  40. #define quad(T) tuple<T, T, T, T>
  41. #define watch(x) cerr << (#x) << " = " << (x) << endl;
  42.  
  43. #ifdef MAX_HOME
  44. #define cerr cout
  45. #else
  46. #define cerr if (false) cerr
  47. #endif
  48.  
  49. const double PI = 2 * acos(0.0);
  50. #define rand shittttty_shit
  51. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  52. mt19937_64 rng_64(chrono::steady_clock::now().time_since_epoch().count());
  53.  
  54. const string DIGITS = "0123456789";
  55. const string ALPH = "abcdefghijklmnopqrstuvwxyz";
  56.  
  57. template <class T0, class T1>
  58. inline ostream & operator << (ostream &out, pair<T0, T1> &a) {
  59.     return out << "{" << a.first << ", " << a.second << "}";
  60. }
  61.  
  62. template <class T0, class T1, class T2>
  63. inline ostream & operator << (ostream &out, tuple<T0, T1, T2> &a) {
  64.     return out << "{" << get<0>(a) << ", " << get<1>(a) << ", " << get<2>(a) << "}";
  65. }
  66.  
  67. template <class T0, class T1, class T2, class T3>
  68. inline ostream & operator << (ostream &out, tuple<T0, T1, T2, T3> &a) {
  69.     return out << "{" << get<0>(a) << ", " << get<1>(a) << ", " << get<2>(a) << ", " <<  get<3>(a) << "}";
  70. }
  71.  
  72. template<class T>
  73. inline ostream & operator << (ostream &out, vector<T> &a) {
  74.     out << "[";
  75.     fori (i, a.size())
  76.         out << a[i] << vector<string>{", ", "]  "}[i + 1 == a.size()];
  77.     return out;
  78. }
  79.  
  80.  
  81.  
  82. void smain();
  83.  
  84. signed main() {
  85.     ios::sync_with_stdio(0);
  86.     cin.tie(0); cout.tie(0);
  87.  
  88. #ifdef MAX_HOME
  89.     freopen("input.txt", "r", stdin);
  90.     clock_t start = clock();
  91. #endif
  92.     cout << setprecision(12) << fixed;
  93.     smain();
  94. #ifdef MAX_HOME
  95.     cout << "\n\n\n\nTOTAL EXECUTION TIME: " << float( clock () - start ) /  CLOCKS_PER_SEC << endl;
  96. #endif
  97.     return 0;
  98. }
  99.  
  100.  
  101.  
  102. namespace naive {
  103.     int naive2(vector<pii> a) {
  104.         int n = a.size();
  105.         const int oo = 1e9;
  106.         vvi dp(1 << n, vi(n, oo));
  107.  
  108.         vvi from(1 << n, vi(n, -1));
  109.  
  110.         for (int mask = 1; mask < (1 << n); ++mask) {
  111.             if (__builtin_popcount(mask) == 1) {
  112.                 int id;
  113.                 fori (i, n) {
  114.                     if ((mask >> i) & 1)
  115.                         id = i;
  116.                 }
  117.                 dp[mask][id] = abs(a[id].first);
  118.                 continue;
  119.             }
  120.  
  121.             fori (i, n) {
  122.                 if (!((mask >> i) & 1))
  123.                     continue;
  124.                 fori (j, n) {
  125.                     if (!((mask >> j) & 1))
  126.                         continue;
  127.                     int vl = dp[mask ^ (1 << i)][j] + abs(a[i].first - a[j].second);
  128.                     if (dp[mask][i] > vl) {
  129.                         dp[mask][i] = vl;
  130.                         from[mask][i] = j;
  131.                     }
  132.                 }
  133.             }
  134.         }
  135.  
  136.         int allmask = (1 << n) - 1;
  137.         int ans = oo;
  138.         fori (i, n) {
  139.             inmin(ans, dp[allmask][i] + abs(a[i].second));
  140.         }
  141.         fori (i, n) {
  142.             if (ans == dp[allmask][i] + abs(a[i].second)) {
  143.                 watch(i);
  144.             }
  145.         }
  146.         return ans;
  147.     }
  148. }
  149.  
  150. namespace mark {
  151.  
  152.     class Edge {
  153.         ///nodes
  154.         int right;
  155.         int left;
  156.  
  157.         double value;
  158.     public:
  159.         Edge(int right, int left, double value) :
  160.                 right(right), left(left), value(value) {
  161.         }
  162.  
  163.         int getRight() const {
  164.             return right;
  165.         }
  166.  
  167.         void setRight(int right) {
  168.             Edge::right = right;
  169.         }
  170.  
  171.         int getLeft() const {
  172.             return left;
  173.         }
  174.  
  175.         void setLeft(int left) {
  176.             Edge::left = left;
  177.         }
  178.  
  179.         double getValue() const {
  180.             return value;
  181.         }
  182.  
  183.         void setValue(double value) {
  184.             Edge::value = value;
  185.         }
  186.  
  187.  
  188.         virtual ~Edge() {
  189.  
  190.         }
  191.  
  192.         friend ostream &operator<<(ostream &os, const Edge &edge) {
  193.             os << " left: " << edge.left
  194.                << " right: " << edge.right
  195.                << " value: " << edge.value
  196.                << endl;
  197.             return os;
  198.         }
  199.  
  200.         bool operator==(const Edge &rhs) const {
  201.             return this->value == rhs.value;
  202.         }
  203.  
  204.         bool operator<(const Edge &rhs) const {
  205.  
  206.             return this->value < rhs.value;
  207.  
  208.         }
  209.  
  210.         bool operator>(const Edge &rhs) const {
  211.             return rhs < *this;
  212.         }
  213.  
  214.         bool operator<=(const Edge &rhs) const {
  215.             return !(rhs < *this);
  216.         }
  217.  
  218.         bool operator>=(const Edge &rhs) const {
  219.             return !(*this < rhs);
  220.         }
  221.  
  222.         bool operator!=(const Edge &rhs) const {
  223.             return !(rhs == *this);
  224.         }
  225.  
  226.         bool more_then(Edge &edge) {
  227.             return this->value >= edge.value;
  228.         }
  229.  
  230.     };
  231.  
  232.  
  233.  
  234.  
  235.     int main(int n, vector<vector<int>> inp) {
  236.  
  237.         int N = n;
  238.         double H = 1;
  239.         const int INF = 1e9;
  240.         int output[N];
  241.  
  242.  
  243.         if (n == 1) {
  244.             output[0] = 0;
  245.         } else {
  246.  
  247. //4
  248. //-500 1000 500
  249. //100 500 200
  250. //0 200 1000
  251. //-100 100 100
  252.  
  253.  
  254.  
  255. //        ifstream infile;
  256. //        infile.open("/Users/lucky.mz/ClionProjects/alg/input.txt");
  257.  
  258. //        if (!infile) {
  259. //            cout << "unable to open file";
  260. //            return false;
  261. //        }
  262.  
  263. //        string sent;
  264. //        if (getline (infile, sent)) {
  265. //            N = stoi(sent);
  266. //            cout << "N = " << N << endl;
  267. //        }
  268.  
  269.  
  270.             double *alpha = new double[N];
  271.             double *omega = new double[N];
  272.             double matrix[N][N];
  273.  
  274.             for (int n = 0; n < N; n++) {
  275.                 for (int m = 0; m < N; m++) {
  276.                     matrix[n][m] = -1;
  277.                 }
  278. //            cout << endl;
  279.             }
  280.  
  281.             for (int k = 0; k < N; ++k) {
  282.                 alpha[k] = 0;
  283.                 omega[k] = 0;
  284.             }
  285.  
  286.             double *cords = new double[3];
  287.             int index;
  288.             int current_N = 0;
  289.             double weight_l;
  290.             double weight_r;
  291.  
  292.             vector<int> mb_start;
  293.             vector<int> mb_finish;
  294.  
  295.  
  296.             ///-------------Start-------------------------------
  297.             for (int iter = 0; iter < N; ++iter) {
  298. //            istringstream iss(sent);
  299.                 string s;
  300.                 index = 0;
  301.                 double angle_a, angle_o = 0;
  302. //            while ( getline( iss, s, ' ' ) ) {
  303. //            printf( "`%s'\n", s.c_str() );
  304. //                cords[index] = stoi(s.c_str());
  305. //                ++index;
  306. //            }
  307.                 cords[0] = inp[current_N][0], cords[1] = inp[current_N][1], cords[2] = inp[current_N][2];
  308. //            cout << "current_N = " << current_N << " | ";
  309. //            cout << cords[0] << " " << cords[1] << " " << cords[2] << endl;
  310.  
  311.                 ///Angle Alpha
  312.                 if (cords[0] == 0) {
  313.                     angle_a = 90;
  314. //            matrix[current_N][current_N] -= 1;
  315.                 } else {
  316.                     if (cords[0] < 0) {
  317.                         angle_a = 180 - (atan(H / abs(cords[0])) * 180 / PI);
  318.                     } else {
  319.                         angle_a = atan(H / cords[0]) * 180 / PI;
  320.                     }
  321.                 }
  322.  
  323.                 ///Angle Omega
  324.                 if (cords[1] == cords[2]) {
  325.                     angle_o = 90;
  326. //            matrix[current_N][current_N] -= 2;
  327.                 } else {
  328.                     if (cords[1] > cords[2]) {
  329.                         angle_o = atan(H / (cords[1] - cords[2])) * 180 / PI;
  330.                     } else {
  331.                         angle_o = 180 - (atan(H / (cords[2] - cords[1])) * 180 / PI);
  332.                     }
  333.                 }
  334. //            cout << "Alpha = " << angle_a << " Omega = " << angle_o << endl;
  335.                 alpha[current_N] = angle_a;
  336.                 omega[current_N] = angle_o;
  337.                 if (current_N > 0) {
  338.                     for (int i = 0; i < current_N; ++i) {
  339.                         if (current_N != i) {
  340.                             weight_l = abs(angle_a - omega[i]);
  341.                             weight_r = abs(angle_o - alpha[i]);
  342.                             matrix[current_N][i] = weight_l;
  343.                             matrix[i][current_N] = weight_r;
  344.                         }
  345.                     }
  346.  
  347.                 }
  348.                 ++current_N;
  349.  
  350.             }
  351. //
  352. //        for (int j = 2; j < N +2 ; ++j) {
  353. //            matrix[0][j] = abs(90 - omega[j]);
  354. //        }
  355. //        for (int l = 2; l < N + 2; ++l) {
  356. //            matrix[l][1] = abs(90 - alpha[l]);
  357. //        }
  358.  
  359.  
  360.  
  361.             vector<Edge> edges;
  362.  
  363.  
  364.  
  365.             ///---------Matrix------------------------
  366. //        cout << "--------------" << endl;
  367. //        cout << endl << "Matrix incident" << endl;
  368.             for (int n = 0; n < N; n++) {
  369.                 for (int m = 0; m < N; m++) {
  370.                     if (matrix[n][m] >= 0) {
  371.                         edges.emplace_back(n, m, matrix[n][m]);
  372.                     } else {
  373.  
  374.                     }
  375. //                cout << matrix[n][m] << " ";
  376.                 }
  377. //            cout << endl;
  378.             }
  379. //        cout << endl;
  380.             ///----------karsakal--------------------------
  381.             sort(edges.begin(), edges.end());
  382.  
  383. //    for (int j = 0; j < edges.size(); ++j) {
  384. //        cout << edges[j];
  385. //    }
  386.  
  387.  
  388.             vector<Edge>
  389.                     result;
  390.             vector<int> right_used;
  391.             vector<int> left_used;
  392.  
  393.             vector<int> comp(N);
  394.             for (int i = 0; i < N; ++i)
  395.                 comp[i] = i;
  396.             double ans = 0;
  397.  
  398.  
  399.             for (auto &edge: edges) {
  400.                 if (find(right_used.begin(),
  401.                          right_used.end(), edge.getRight())
  402.                     != right_used.end()
  403.                     ||
  404.                     find(left_used.begin(),
  405.                          left_used.end(), edge.getLeft())
  406.                     != left_used.end()) {
  407.                     continue;
  408.                 } else {
  409.                     double weight = edge.getValue();
  410.                     int start = edge.getLeft();
  411.                     int end = edge.getRight();
  412.                     if (comp[start] != comp[end]) {
  413.                         ans += weight;
  414.                         result.push_back(edge);
  415.                         right_used.push_back(edge.getRight());
  416.                         left_used.push_back(edge.getLeft());
  417.                         int a = comp[start];
  418.                         int b = comp[end];
  419.                         for (int i = 0; i < N; ++i)
  420.                             if (comp[i] == b)
  421.                                 comp[i] = a;
  422.                     }
  423.                 }
  424.             }
  425.  
  426.             vector<int> left;
  427.             vector<int> right;
  428.  
  429. //        cout << "--------------" << endl;
  430.             for (int j = 0; j < result.size(); ++j) {
  431. //            cout << result[j];
  432.                 left.push_back(result[j].getLeft());
  433.                 right.push_back(result[j].getRight());
  434.             }
  435.             current_N = 0;
  436.             while (true) {
  437.                 if (find(right.begin(),
  438.                          right.end(), left[current_N])
  439.                     == right.end()) {
  440.                     break;
  441.                 } else ++current_N;
  442.             }
  443.             //start trap current_N
  444. //        cout << endl << ans << endl;
  445.             int next;
  446.  
  447.             for (int l = 0; l < N - 1; ++l) {
  448.                 output[l] = result[current_N].getLeft();
  449.                 next = result[current_N].getRight();
  450.                 for (int i = 0; i < result.size(); ++i) {
  451.                     if (result[i].getLeft() == next) {
  452.                         current_N = i;
  453.                         break;
  454.                     }
  455.                 }
  456.             }
  457.             output[N - 1] = result[current_N].getRight();
  458.         }
  459.  
  460. //        ofstream outfile;
  461. //        outfile.open ("/Users/lucky.mz/ClionProjects/alg/output.txt");
  462.         int cost = 0;
  463.         int prv = 0;
  464.         for (int i = 0; i < N; ++i) {
  465. //            cout << output[i] << " ";
  466.             int id = output[i];
  467.             cost += abs(prv - inp[id][0]);
  468.             prv = inp[id][1] - inp[id][2];
  469. //            outfile << output[i] << " ";
  470.  
  471.         }
  472.  
  473.         cost += abs(prv);
  474.  
  475.  
  476.  
  477.  
  478. //        outfile.close();
  479.  
  480.         return cost;
  481.     }
  482.  
  483.  
  484. }
  485.  
  486. void stress() {
  487.     int cnt = 0;
  488.     const int SHIFT = 100;
  489.     while (true) {
  490.         if (++cnt % 1 == 0)
  491.             watch(cnt);
  492.         int n = rng() % 2 + 1;
  493.         vector<pii> a(n);
  494.         fori (i, n) {
  495.             a[i] = {rng() % 100 - 50, rng() % 100 - 50};
  496.         }
  497.  
  498.         int nv = naive::naive2(a);
  499.         vvi inp(a.size());
  500.         fori (i, SZ(a)) {
  501.             inp[i] = {a[i].first, a[i].second + SHIFT, SHIFT};
  502.         }
  503.         int sl = mark::main(a.size(), inp);
  504.         if (sl != nv) {
  505.             watch(cnt);
  506.             cout << n << '\n';
  507.             for (auto x : a) {
  508.                 cout << x.first << ' ' << x.second + SHIFT << " " << SHIFT << '\n';
  509.             }
  510.             watch(sl);
  511.             watch(nv);
  512.             return;
  513.         }
  514.     }
  515. }
  516.  
  517. void smain() {
  518.  
  519. //    stress();
  520. //    return;
  521.  
  522.  
  523.     int n;
  524.     cin >> n;
  525.     vector<pii> a(n);
  526.     fori (i, n) {
  527.         int x, y;
  528.         cin >> a[i].first >> x >> y;
  529.         a[i].second = x - y;
  530.     }
  531.     int nv = naive::naive2(a);
  532.     vvi b(a.size());
  533.     for (int i = 0; i < SZ(a); ++i) {
  534.         b[i] = {a[i].first, a[i].second, 0};
  535.     }
  536.     int sl = 0;
  537.     sl = mark::main(a.size(), b);
  538.     cerr << endl;
  539.     watch(nv);
  540.     watch(sl);
  541. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement