Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <random>
- using namespace std;
- typedef unsigned long long ull;
- typedef long long ll;
- typedef long double ld;
- //#define int ll
- typedef pair<int, int> pii;
- typedef pair<pii, pii> piii;
- typedef pair<ll, ll> pll;
- typedef vector<int> vi;
- typedef vector<pii> vpi;
- typedef vector< vi > vvi;
- typedef vector< vvi > vvvi;
- typedef vector<short> vs;
- typedef vector<vs> vvs;
- typedef vector<vvs> vvvs;
- typedef vector<ll> vl;
- typedef vector<vl> vvl;
- typedef vector<vvl> vvvl;
- typedef vector<ld> vld;
- typedef vector<vld> vvld;
- typedef vector<vvld> vvvld;
- typedef vector<string> vst;
- typedef vector<vst> vvst;
- typedef pair<ld, ld> pld;
- typedef complex<double> base;
- #define inmin(a, b) a = min(a, (b))
- #define inmax(a, b) a = max(a, (b))
- #define mp(a, b) make_pair((a), (b))
- #define ALL(a) a.begin(),a.end()
- #define RALL(a) a.rbegin(),a.rend()
- #define sqr(x) ((x) * (x))
- #define fori(i, n) for(int i = 0; i < int(n); ++i)
- #define SZ(a) ((int)((a).size()))
- #define triple(T) tuple<T, T, T>
- #define quad(T) tuple<T, T, T, T>
- #define watch(x) cerr << (#x) << " = " << (x) << endl;
- #ifdef MAX_HOME
- #define cerr cout
- #else
- #define cerr if (false) cerr
- #endif
- const double PI = 2 * acos(0.0);
- #define rand shittttty_shit
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- mt19937_64 rng_64(chrono::steady_clock::now().time_since_epoch().count());
- const string DIGITS = "0123456789";
- const string ALPH = "abcdefghijklmnopqrstuvwxyz";
- template <class T0, class T1>
- inline ostream & operator << (ostream &out, pair<T0, T1> &a) {
- return out << "{" << a.first << ", " << a.second << "}";
- }
- template <class T0, class T1, class T2>
- inline ostream & operator << (ostream &out, tuple<T0, T1, T2> &a) {
- return out << "{" << get<0>(a) << ", " << get<1>(a) << ", " << get<2>(a) << "}";
- }
- template <class T0, class T1, class T2, class T3>
- inline ostream & operator << (ostream &out, tuple<T0, T1, T2, T3> &a) {
- return out << "{" << get<0>(a) << ", " << get<1>(a) << ", " << get<2>(a) << ", " << get<3>(a) << "}";
- }
- template<class T>
- inline ostream & operator << (ostream &out, vector<T> &a) {
- out << "[";
- fori (i, a.size())
- out << a[i] << vector<string>{", ", "] "}[i + 1 == a.size()];
- return out;
- }
- void smain();
- signed main() {
- ios::sync_with_stdio(0);
- cin.tie(0); cout.tie(0);
- #ifdef MAX_HOME
- freopen("input.txt", "r", stdin);
- clock_t start = clock();
- #endif
- cout << setprecision(12) << fixed;
- smain();
- #ifdef MAX_HOME
- cout << "\n\n\n\nTOTAL EXECUTION TIME: " << float( clock () - start ) / CLOCKS_PER_SEC << endl;
- #endif
- return 0;
- }
- namespace naive {
- int naive2(vector<pii> a) {
- int n = a.size();
- const int oo = 1e9;
- vvi dp(1 << n, vi(n, oo));
- vvi from(1 << n, vi(n, -1));
- for (int mask = 1; mask < (1 << n); ++mask) {
- if (__builtin_popcount(mask) == 1) {
- int id;
- fori (i, n) {
- if ((mask >> i) & 1)
- id = i;
- }
- dp[mask][id] = abs(a[id].first);
- continue;
- }
- fori (i, n) {
- if (!((mask >> i) & 1))
- continue;
- fori (j, n) {
- if (!((mask >> j) & 1))
- continue;
- int vl = dp[mask ^ (1 << i)][j] + abs(a[i].first - a[j].second);
- if (dp[mask][i] > vl) {
- dp[mask][i] = vl;
- from[mask][i] = j;
- }
- }
- }
- }
- int allmask = (1 << n) - 1;
- int ans = oo;
- fori (i, n) {
- inmin(ans, dp[allmask][i] + abs(a[i].second));
- }
- fori (i, n) {
- if (ans == dp[allmask][i] + abs(a[i].second)) {
- watch(i);
- }
- }
- return ans;
- }
- }
- namespace mark {
- class Edge {
- ///nodes
- int right;
- int left;
- double value;
- public:
- Edge(int right, int left, double value) :
- right(right), left(left), value(value) {
- }
- int getRight() const {
- return right;
- }
- void setRight(int right) {
- Edge::right = right;
- }
- int getLeft() const {
- return left;
- }
- void setLeft(int left) {
- Edge::left = left;
- }
- double getValue() const {
- return value;
- }
- void setValue(double value) {
- Edge::value = value;
- }
- virtual ~Edge() {
- }
- friend ostream &operator<<(ostream &os, const Edge &edge) {
- os << " left: " << edge.left
- << " right: " << edge.right
- << " value: " << edge.value
- << endl;
- return os;
- }
- bool operator==(const Edge &rhs) const {
- return this->value == rhs.value;
- }
- bool operator<(const Edge &rhs) const {
- return this->value < rhs.value;
- }
- bool operator>(const Edge &rhs) const {
- return rhs < *this;
- }
- bool operator<=(const Edge &rhs) const {
- return !(rhs < *this);
- }
- bool operator>=(const Edge &rhs) const {
- return !(*this < rhs);
- }
- bool operator!=(const Edge &rhs) const {
- return !(rhs == *this);
- }
- bool more_then(Edge &edge) {
- return this->value >= edge.value;
- }
- };
- int main(int n, vector<vector<int>> inp) {
- int N = n;
- double H = 1;
- const int INF = 1e9;
- int output[N];
- if (n == 1) {
- output[0] = 0;
- } else {
- //4
- //-500 1000 500
- //100 500 200
- //0 200 1000
- //-100 100 100
- // ifstream infile;
- // infile.open("/Users/lucky.mz/ClionProjects/alg/input.txt");
- // if (!infile) {
- // cout << "unable to open file";
- // return false;
- // }
- // string sent;
- // if (getline (infile, sent)) {
- // N = stoi(sent);
- // cout << "N = " << N << endl;
- // }
- double *alpha = new double[N];
- double *omega = new double[N];
- double matrix[N][N];
- for (int n = 0; n < N; n++) {
- for (int m = 0; m < N; m++) {
- matrix[n][m] = -1;
- }
- // cout << endl;
- }
- for (int k = 0; k < N; ++k) {
- alpha[k] = 0;
- omega[k] = 0;
- }
- double *cords = new double[3];
- int index;
- int current_N = 0;
- double weight_l;
- double weight_r;
- vector<int> mb_start;
- vector<int> mb_finish;
- ///-------------Start-------------------------------
- for (int iter = 0; iter < N; ++iter) {
- // istringstream iss(sent);
- string s;
- index = 0;
- double angle_a, angle_o = 0;
- // while ( getline( iss, s, ' ' ) ) {
- // printf( "`%s'\n", s.c_str() );
- // cords[index] = stoi(s.c_str());
- // ++index;
- // }
- cords[0] = inp[current_N][0], cords[1] = inp[current_N][1], cords[2] = inp[current_N][2];
- // cout << "current_N = " << current_N << " | ";
- // cout << cords[0] << " " << cords[1] << " " << cords[2] << endl;
- ///Angle Alpha
- if (cords[0] == 0) {
- angle_a = 90;
- // matrix[current_N][current_N] -= 1;
- } else {
- if (cords[0] < 0) {
- angle_a = 180 - (atan(H / abs(cords[0])) * 180 / PI);
- } else {
- angle_a = atan(H / cords[0]) * 180 / PI;
- }
- }
- ///Angle Omega
- if (cords[1] == cords[2]) {
- angle_o = 90;
- // matrix[current_N][current_N] -= 2;
- } else {
- if (cords[1] > cords[2]) {
- angle_o = atan(H / (cords[1] - cords[2])) * 180 / PI;
- } else {
- angle_o = 180 - (atan(H / (cords[2] - cords[1])) * 180 / PI);
- }
- }
- // cout << "Alpha = " << angle_a << " Omega = " << angle_o << endl;
- alpha[current_N] = angle_a;
- omega[current_N] = angle_o;
- if (current_N > 0) {
- for (int i = 0; i < current_N; ++i) {
- if (current_N != i) {
- weight_l = abs(angle_a - omega[i]);
- weight_r = abs(angle_o - alpha[i]);
- matrix[current_N][i] = weight_l;
- matrix[i][current_N] = weight_r;
- }
- }
- }
- ++current_N;
- }
- //
- // for (int j = 2; j < N +2 ; ++j) {
- // matrix[0][j] = abs(90 - omega[j]);
- // }
- // for (int l = 2; l < N + 2; ++l) {
- // matrix[l][1] = abs(90 - alpha[l]);
- // }
- vector<Edge> edges;
- ///---------Matrix------------------------
- // cout << "--------------" << endl;
- // cout << endl << "Matrix incident" << endl;
- for (int n = 0; n < N; n++) {
- for (int m = 0; m < N; m++) {
- if (matrix[n][m] >= 0) {
- edges.emplace_back(n, m, matrix[n][m]);
- } else {
- }
- // cout << matrix[n][m] << " ";
- }
- // cout << endl;
- }
- // cout << endl;
- ///----------karsakal--------------------------
- sort(edges.begin(), edges.end());
- // for (int j = 0; j < edges.size(); ++j) {
- // cout << edges[j];
- // }
- vector<Edge>
- result;
- vector<int> right_used;
- vector<int> left_used;
- vector<int> comp(N);
- for (int i = 0; i < N; ++i)
- comp[i] = i;
- double ans = 0;
- for (auto &edge: edges) {
- if (find(right_used.begin(),
- right_used.end(), edge.getRight())
- != right_used.end()
- ||
- find(left_used.begin(),
- left_used.end(), edge.getLeft())
- != left_used.end()) {
- continue;
- } else {
- double weight = edge.getValue();
- int start = edge.getLeft();
- int end = edge.getRight();
- if (comp[start] != comp[end]) {
- ans += weight;
- result.push_back(edge);
- right_used.push_back(edge.getRight());
- left_used.push_back(edge.getLeft());
- int a = comp[start];
- int b = comp[end];
- for (int i = 0; i < N; ++i)
- if (comp[i] == b)
- comp[i] = a;
- }
- }
- }
- vector<int> left;
- vector<int> right;
- // cout << "--------------" << endl;
- for (int j = 0; j < result.size(); ++j) {
- // cout << result[j];
- left.push_back(result[j].getLeft());
- right.push_back(result[j].getRight());
- }
- current_N = 0;
- while (true) {
- if (find(right.begin(),
- right.end(), left[current_N])
- == right.end()) {
- break;
- } else ++current_N;
- }
- //start trap current_N
- // cout << endl << ans << endl;
- int next;
- for (int l = 0; l < N - 1; ++l) {
- output[l] = result[current_N].getLeft();
- next = result[current_N].getRight();
- for (int i = 0; i < result.size(); ++i) {
- if (result[i].getLeft() == next) {
- current_N = i;
- break;
- }
- }
- }
- output[N - 1] = result[current_N].getRight();
- }
- // ofstream outfile;
- // outfile.open ("/Users/lucky.mz/ClionProjects/alg/output.txt");
- int cost = 0;
- int prv = 0;
- for (int i = 0; i < N; ++i) {
- // cout << output[i] << " ";
- int id = output[i];
- cost += abs(prv - inp[id][0]);
- prv = inp[id][1] - inp[id][2];
- // outfile << output[i] << " ";
- }
- cost += abs(prv);
- // outfile.close();
- return cost;
- }
- }
- void stress() {
- int cnt = 0;
- const int SHIFT = 100;
- while (true) {
- if (++cnt % 1 == 0)
- watch(cnt);
- int n = rng() % 2 + 1;
- vector<pii> a(n);
- fori (i, n) {
- a[i] = {rng() % 100 - 50, rng() % 100 - 50};
- }
- int nv = naive::naive2(a);
- vvi inp(a.size());
- fori (i, SZ(a)) {
- inp[i] = {a[i].first, a[i].second + SHIFT, SHIFT};
- }
- int sl = mark::main(a.size(), inp);
- if (sl != nv) {
- watch(cnt);
- cout << n << '\n';
- for (auto x : a) {
- cout << x.first << ' ' << x.second + SHIFT << " " << SHIFT << '\n';
- }
- watch(sl);
- watch(nv);
- return;
- }
- }
- }
- void smain() {
- // stress();
- // return;
- int n;
- cin >> n;
- vector<pii> a(n);
- fori (i, n) {
- int x, y;
- cin >> a[i].first >> x >> y;
- a[i].second = x - y;
- }
- int nv = naive::naive2(a);
- vvi b(a.size());
- for (int i = 0; i < SZ(a); ++i) {
- b[i] = {a[i].first, a[i].second, 0};
- }
- int sl = 0;
- sl = mark::main(a.size(), b);
- cerr << endl;
- watch(nv);
- watch(sl);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement