QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#198274#4246. Cactus is MoneyUnknown1508WA 0ms3876kbC++203.8kb2023-10-03 11:47:272023-10-03 11:47:27

Judging History

你现在查看的是最新测评结果

  • [2023-10-03 11:47:27]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3876kb
  • [2023-10-03 11:47:27]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

void main_program();

signed main(){
	ios_base::sync_with_stdio(0); cin.tie(0);
	main_program();
}

using ll = long long;
using ld = long double;

struct Point{
	ll x, y;

	Point() {}
	Point(ll _x, ll _y): x(_x), y(_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 - () const {
		return Point(-x, -y);
	}

	bool operator < (const Point &P) const {
		if (y != P.y) return y < P.y;
		return x < P.x;
	}
};

struct Line{
	ll A, B, C;

	Line() {}
	Line(ll _A, ll _B, ll _C): A(_A), B(_B), C(_C) {}
	Line(Point p1, Point p2){
		A = p1.y - p2.y;
		B = p2.x - p1.x;
		C = -A * p1.x - B * p1.y;
	}
};

ld cross(Point p1, Point p2){
	return p1.x * p2.y - p1.y * p2.x;
}

using Polygon = vector<Point>;

void reorder(Polygon &p){
	int root = 0;
	for (int i = 0; i < p.size(); i++){
		if (p[i] < p[root]) root = i;
	}
	rotate(p.begin(), p.begin() + root, p.end());
}

Polygon mincowski_sum(Polygon A, Polygon B){
	reorder(A); reorder(B);
	A.push_back(A[0]);
	A.push_back(A[1]);
	B.push_back(B[0]);
	B.push_back(B[1]);

	Polygon res;
	int i = 0, j = 0;
	while (i < A.size() - 2 || j < B.size() - 2){
		res.push_back(A[i] + B[j]);
		ld C = cross(A[i+1] - A[i], B[j+1] - B[j]);
		if (C >= 0 && i < A.size() - 2) i++;
		if (C <= 0 && j < B.size() - 2) j++;
	}
	return res;
}

ll orientation(Point A, Point B, Point C){
	ll v = A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y);
	if (v < 0) return -1;
	if (v > 0) return 1;
	return 0;
}

bool cw(Point A, Point B, Point C){
	int o = orientation(A, B, C);
	return o < 0;
}

ll sq(ll x) { return x * x; }

Polygon convex_hull(Polygon &vec){
	Point root = *min_element(vec.begin(), vec.end());
	sort(vec.begin(), vec.end(), [&](const Point &A, const Point &B){
		int o = orientation(root, A, B);
		if (o == 0){
			return sq(root.x - A.x) + sq(root.y - A.y)
			< sq(root.x - B.x) + sq(root.y - B.y);
		}
		return o < 0;
	});

	Polygon res;
	for (int i = 0; i < (int)vec.size(); i++){
		while (res.size() > 1 && !cw(end(res)[-2], end(res)[-1], vec[i])){
			res.pop_back();
		}
		res.push_back(vec[i]);
	}

	return res;
}

struct Edge{
	int nxt;
	ll a, b;
};

int n, m;
ll A = 0, B = 0;
vector<int> depth, vst;
vector<vector<Edge>> adj;
vector<vector<Edge>> cycles;
vector<Edge> path;

void dfs(int x, int p = -1, int d = 0){
	depth[x] = d;
	vst[x] = 1;

	for (auto edge: adj[x]){
		int k = edge.nxt;
		if (k == p) continue;

		if (vst[k]){
			int diff = depth[x] - depth[k];
			if (diff > 0){
				cycles.emplace_back();
				cycles.back().push_back(edge);
				for (int i = 1; i <= diff; i++){
					cycles.back().push_back(end(path)[-i]);
				}
			}
		}
		else{
			path.push_back(edge);
			dfs(k, x, d+1);
			path.pop_back();
		}
	}
}

auto greater_by_size = [](const Polygon &p1, const Polygon &p2){
	return p1.size() > p2.size();
};
priority_queue<Polygon, vector<Polygon>, decltype(greater_by_size)> pq;

void main_program(){
	cin >> n >> m;

	depth.resize(n);
	vst.resize(n);
	adj.resize(n);

	for (int i = 0; i < n; i++){
		int x, y, a, b; cin >> x >> y >> a >> b;
		x--; y--;
		adj[x].push_back(Edge{y, a, b});
		adj[y].push_back(Edge{x, a, b});
		A += a; B += b;
	}

	dfs(0);

	for (auto cyc: cycles){
		Polygon crr;
		for (auto edge: cyc){
			crr.emplace_back(edge.a, edge.b);
		}
		pq.push(convex_hull(crr));
	}

	while (pq.size() >= 2){
		Polygon p1 = pq.top(); pq.pop();
		Polygon p2 = pq.top(); pq.pop();
		Polygon pmerge = mincowski_sum(p1, p2);
		pq.push(pmerge);
	}

	Polygon final = pq.top();

	ll opt = 1e18;
	for (auto pt: final){
		opt = min(opt, (A - pt.x) * (B - pt.y));
	}

	cout << opt << "\n";
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3876kb

input:

3 3
1 2 0 1000
2 3 0 1000
3 1 1 1

output:

0

result:

ok 1 number(s): "0"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3624kb

input:

5 5
1 2 666 10
2 3 555 1000
3 1 444 345
1 4 222 234
2 5 333 123

output:

1185480

result:

ok 1 number(s): "1185480"

Test #3:

score: -100
Wrong Answer
time: 0ms
memory: 3584kb

input:

5 6
1 3 12316 13729
1 2 171 10309
5 1 47389 7369
2 4 43318 36867
1 4 30728 43835
5 3 24437 31639

output:

6817226168

result:

wrong answer 1st numbers differ - expected: '6732185824', found: '6817226168'