Submission #300750

# Submission time Handle Problem Language Result Execution time Memory
300750 2020-09-17T13:08:43 Z Mohammad_Yasser timeismoney (balkan11_timeismoney) C++14
40 / 100
2000 ms 65540 KB
#ifndef Local
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse4,sse4.2,popcnt,abm,mmx,avx")
#endif
#include <bits/stdc++.h>

using namespace std;

#define popCnt(x) (__builtin_popcountll(x))
#define sz(x) ((int)(x.size()))
#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
typedef long long Long;
typedef double Double;

template <class U, class V>
istream& operator>>(istream& is, pair<U, V>& p) {
  is >> p.first >> p.second;
  return is;
}
template <class T>
istream& operator>>(istream& is, vector<T>& v) {
  for (auto& x : v) {
    is >> x;
  }
  return is;
}

template <class T>
ostream& operator<<(ostream& os, vector<T>& v) {
  for (auto& x : v) {
    os << x << " ";
  }
  return os;
}

const Double EPS = 1e-10;

enum Relation { LESS_THAN, EQUAL, GREATER_THAN };

bool areEqual(Double x, Double y, Double eps = EPS) {
  auto diff = abs(x - y);
  x = abs(x), y = abs(y);
  if (diff <= eps) return true;
  if (min(x, y) <= eps) return false;
  return diff <= eps * max(x, y);
}

bool isZero(Double x, Double eps = EPS) { return abs(x) <= eps; }
bool isZero(Long x) { return x == 0; }

int compareDoubles(Double x, Double y, Double eps = EPS) {
  if (areEqual(x, y, eps)) return Relation::EQUAL;
  if (x < y) return Relation::LESS_THAN;
  return Relation::GREATER_THAN;
}

template <typename T = Double>
struct Point {
  typedef Point P;
  const static P Invalid;
  const static P Origin;

  T x = 0, y = 0;
  Point(T x, T y) : x(x), y(y) {}
  Point() {}
  pair<T, T> to_pair() const { return make_pair(x, y); }
  Point operator+(const Point& p) const { return Point{x + p.x, y + p.y}; }
  Point operator-(const Point& p) const { return Point{x - p.x, y - p.y}; }
  Point operator*(T c) const { return Point(x * c, y * c); }
  Point operator/(T c) const { return Point(x / c, y / c); }
  bool operator<(const Point& p) const {
    return (*this) != p && to_pair() < p.to_pair();
  }
  bool operator>(const Point& p) const { return (*this) != p && !(*this < p); }
  bool operator==(const Point& p) const {
    return isZero(this->x - p.x) && isZero(this->y - p.y);
  }
  bool operator!=(const Point& p) const { return !(*this == p); }
  T cross(const P& p) const { return x * p.y - y * p.x; }
  T cross(const P& a, const P& b) const { return (a - *this).cross(b - *this); }
  T dot(const P& p) const { return x * p.x + y * p.y; }
  P midPoint(const P& p) const { return ((*this) + p) / 2; }
  P getVector(const P& p) const { return p - (*this); }
  T dist2(const P& p) const { return getVector(p).dist2(); }
  T dist2() const { return (*this).dot(*this); }
  Double dist(const P& p) const { return sqrt(dist2(p)); }
  Double dist() const { return sqrt(dist2()); }
  P rotateCCW90() const { return P(-y, x); }
  friend istream& operator>>(istream& is, P& p) { return is >> p.x >> p.y; }

  friend ostream& operator<<(ostream& os, const P& p) {
    return os << p.x << " " << p.y;
  }
};

template <typename T>
const Point<T> Point<T>::Invalid = Point<T>(numeric_limits<T>::max(),
                                            numeric_limits<T>::max());
template <typename T>
const Point<T> Point<T>::Origin = Point<T>(0, 0);

typedef Point<Double> P;

bool areCollinear(const P& a, const P& b, const P& c) {
  return isZero(a.getVector(b).cross(c.getVector(b)));
}

const int N = 200;

struct DSU {
  int parent[N];
  void init() {
    for (int i = 0; i < N; ++i) {
      parent[i] = i;
    }
  }
  int getRoot(int x) {
    if (parent[x] == x) return x;
    return parent[x] = getRoot(parent[x]);
  }
  bool join(int x, int y) {
    x = getRoot(x);
    y = getRoot(y);
    if (x == y) return false;
    parent[x] = y;
    return true;
  }
};

struct Edge {
  int u, v;
  Double t, c;
  bool operator<(const Edge& other) const { return t + c < other.t + other.c; }
};

vector<Edge> edges;

struct Solution {
  uint t = 0, c = 0;
  vector<pair<int, int>> edges;
  P getP() const { return P(t, c); }
  uint score() const { return t * c; }
  bool operator<(const Solution& other) const {
    return score() < other.score();
  }
  bool operator==(const Solution& other) const {
    return t == other.t && c == other.c;
  }
};

Solution mst(const P& coeff) {
  auto edges = ::edges;
  for (auto& edge : edges) {
    edge.t *= coeff.x;
    edge.c *= coeff.y;
  }
  sort(all(edges));
  static DSU dsu;
  dsu.init();
  Solution sol;
  for (auto& edge : edges) {
    if (dsu.join(edge.u, edge.v)) {
      sol.t += round(edge.t / coeff.x), sol.c += round(edge.c / coeff.y);
      sol.edges.emplace_back(edge.u, edge.v);
    }
  }
  return sol;
}
Solution best;
void solve(const P& left_v, const P& right_v, const Solution& left_sol,
           const Solution& right_sol) {
  if (left_sol == right_sol) return;
  P mid = (left_sol.getP() - right_sol.getP()).rotateCCW90();

  auto sol = mst(mid);
  best = min(best, sol);
  solve(left_v, mid, left_sol, sol);
  solve(mid, right_v, sol, right_sol);
}

int main() {
  ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#ifdef Local
  freopen("test.in", "r", stdin);
#else
#define endl '\n'
#endif

  int n, m;
  cin >> n >> m;

  edges.resize(m);
  for (auto& edge : edges) {
    cin >> edge.u >> edge.v >> edge.t >> edge.c;
  }

  P left_v(1e-7, 1);
  P right_v(1, 1e-7);
  auto left_sol = mst(left_v);
  auto right_sol = mst(right_v);
  best = min(left_sol, right_sol);
  solve(left_v, right_v, left_sol, right_sol);
  cout << best.t << " " << best.c << endl;
  for (auto [u, v] : best.edges) {
    cout << u << " " << v << endl;
  }

  return 0;
}

Compilation message

timeismoney.cpp: In function 'int main()':
timeismoney.cpp:205:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  205 |   for (auto [u, v] : best.edges) {
      |             ^
# Verdict Execution time Memory Grader output
1 Correct 1 ms 384 KB Output is correct
2 Correct 1 ms 384 KB Output is correct
3 Correct 1 ms 384 KB Output is correct
4 Correct 1 ms 384 KB Output is correct
5 Correct 1 ms 512 KB Output is correct
6 Correct 1 ms 384 KB Output is correct
7 Correct 2 ms 384 KB Output is correct
8 Correct 9 ms 788 KB Output is correct
9 Runtime error 269 ms 65540 KB Execution killed with signal 9
10 Runtime error 517 ms 65540 KB Execution killed with signal 9
11 Runtime error 255 ms 65540 KB Execution killed with signal 9
12 Runtime error 389 ms 65540 KB Execution killed with signal 9
13 Runtime error 405 ms 65540 KB Execution killed with signal 9
14 Runtime error 1350 ms 65540 KB Execution killed with signal 9
15 Runtime error 559 ms 65540 KB Execution killed with signal 9
16 Execution timed out 2078 ms 26056 KB Time limit exceeded
17 Execution timed out 2060 ms 26464 KB Time limit exceeded
18 Execution timed out 2062 ms 26288 KB Time limit exceeded
19 Execution timed out 2072 ms 4860 KB Time limit exceeded
20 Execution timed out 2058 ms 4820 KB Time limit exceeded