Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "testlib.h"
- #include <bits/stdc++.h>
- using namespace std;
- double EPS = 1e-6;
- template <typename ValueType>
- ValueType sqr(ValueType a) {
- return a * a;
- }
- template <typename ValueType>
- class Point {
- ValueType x, y;
- public:
- explicit Point()
- {}
- explicit Point(const ValueType &x, const ValueType &y):
- x(x), y(y)
- {}
- friend std::istream &operator >> (std::istream &is, Point &point) {
- return is >> point.x >> point.y;
- }
- friend std::ostream &operator << (std::ostream &os, const Point &point) {
- return os << point.x << ' ' << point.y;
- }
- ValueType X() const {
- return x;
- }
- ValueType Y() const {
- return y;
- }
- bool operator < (const Point &other) const {
- return x < other.x || (x == other.x && y < other.y);
- }
- bool operator == (const Point &other) const {
- return x == other.X() && y == other.Y();
- }
- double Distance(const Point &other) const {
- return sqrt(sqr(x - other.X()) + sqr(y - other.Y()));
- }
- };
- template <typename ValueType>
- class PointAndGraph {
- vector <pair<size_t, size_t> > graph;
- vector <Point<ValueType> > point;
- double price;
- double MAX_DISTANCE;
- public:
- explicit PointAndGraph()
- {}
- explicit PointAndGraph(const vector<Point<ValueType> > &point):
- point(point)
- {
- vector<vector<double> > matrix = GetAdjacencyMatrix();
- Prima(matrix);
- }
- vector<vector<double> > GetAdjacencyMatrix() {
- MAX_DISTANCE = 0;
- vector<vector<double> > result(point.size(), vector<double> (point.size(), 0));
- for (size_t i = 0; i < point.size(); ++i) {
- for (size_t j = 0; j < point.size(); ++j) {
- result[i][j] = point[i].Distance(point[j]);
- if (MAX_DISTANCE < result[i][j]) {
- MAX_DISTANCE = result[i][j];
- }
- }
- MAX_DISTANCE *= 2;
- }
- return result;
- }
- void Prima(const vector<vector<double> > &matrix) {
- size_t size = matrix.size(), start = 0;
- vector<char> used(size);
- vector <double> distance(size, MAX_DISTANCE);
- vector<size_t> parent(size);
- distance[start] = 0;
- price = 0;
- for (size_t q = 0; q < size; ++q) {
- size_t index_minimum = size;
- for (size_t index = 0; index < size; ++index) {
- if (!used[index] && (index_minimum == size || distance[index] < distance[index_minimum])) {
- index_minimum = index;
- }
- }
- if (index_minimum == size) {
- continue;
- }
- used[index_minimum] = 1;
- if (index_minimum != start) {
- graph.push_back({index_minimum, parent[index_minimum]});
- price += distance[index_minimum];
- }
- for (size_t index = 0; index < size; ++index) {
- if (!used[index] && distance[index] - EPS > matrix[index_minimum][index]) {
- distance[index] = matrix[index_minimum][index];
- parent[index] = index_minimum;
- }
- }
- }
- }
- vector <pair<size_t, size_t> > GetGraph() const {
- return graph;
- }
- vector <Point<ValueType> > GetPoint() const {
- return point;
- }
- double GetPrice() const {
- return price;
- }
- bool operator < (const PointAndGraph &other) const {
- return price < other.price;
- }
- };
- void ReadVectorPoint(InStream &is, vector<Point<int64_t> >::iterator begin,
- vector<Point<int64_t> >::iterator end, int64_t border, set<Point<int64_t> > &set_point, TResult _pe) {
- for (; begin != end; ++begin) {
- int64_t x = is.readInt(-border, border);
- int64_t y = is.readInt(-border, border);
- (*begin) = Point<int64_t> (x, y);
- if (set_point.count(*begin)) {
- quitf(_pe, "there equal point");
- }
- set_point.insert(*begin);
- }
- }
- double Solve(InStream &is, const vector<Point<int64_t> > &basic, int64_t border, int64_t border_extra_size,
- set<Point<int64_t> > set_point, TResult _pe){
- int extra_size = is.readInt(0, border_extra_size);
- vector<Point<int64_t> > extra_points(extra_size);
- ReadVectorPoint(is, extra_points.begin(), extra_points.end(), border, set_point, _pe);
- double answer = (PointAndGraph<int64_t>(basic)).GetPrice();
- for (int subset = 1; subset != (1 << extra_size); ++subset) {
- vector<Point<int64_t> > points = basic;
- for (int i = 0; i != extra_size; ++i) {
- if (subset & (1 << i)) {
- points.push_back(extra_points[i]);
- }
- }
- answer = std::min(answer, (PointAndGraph<int64_t>(points)).GetPrice());
- }
- return answer;
- }
- int main(int argc, char **argv)
- {
- registerTestlibCmd(argc, argv);
- int basic_size = inf.readInt(), extra_size = inf.readInt();
- if (basic_size < 0 || extra_size < 0) {
- quitf(_fail, "input basic_size = %d, extra_size = %d", basic_size, extra_size);
- }
- vector<Point<int64_t> > basic(basic_size);
- int64_t border = 1e4;
- set<Point<int64_t> > set_point;
- ReadVectorPoint(inf, basic.begin(), basic.end(), border, set_point, _fail);
- double clean_answer = PointAndGraph<int64_t> (basic).GetPrice();
- double best_answer = Solve(ans, basic, border, extra_size, set_point, _fail);
- double user_answer = Solve(ouf, basic, border, extra_size, set_point, _pe);
- quitp(max((double)0, floor(70.0 * (clean_answer - user_answer) / (clean_answer - best_answer))), "");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement