QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#574392 | #5540. City Hall | May_27th | WA | 1ms | 8036kb | C++20 | 2.9kb | 2024-09-18 21:55:42 | 2024-09-18 21:55:47 |
Judging History
answer
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt")
#include<bits/stdc++.h>
using namespace std;
#define i64 long long
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
struct Line {
mutable i64 k, m, p;
bool operator<(const Line& o) const { return k < o.k; }
bool operator<(i64 x) const { return p < x; }
};
struct LineContainer : multiset<Line, less<>> {
// (for doubles, use inf = 1/.0, div(a,b) = a/b)
static const i64 inf = 1e18;
i64 div(i64 a, i64 b) { // floored division
return a / b - ((a ^ b) < 0 && a % b); }
bool isect(iterator x, iterator y) {
if (y == end()) return x->p = inf, 0;
if (x->k == y->k) x->p = x->m > y->m ? inf : -inf;
else x->p = div(y->m - x->m, x->k - y->k);
return x->p >= y->p;
}
void add(i64 k, i64 m) {
auto z = insert({k, m, 0}), y = z++, x = y;
while (isect(y, z)) z = erase(z);
if (x != begin() && isect(--x, y)) isect(x, y = erase(y));
while ((y = x) != begin() && (--x)->p >= y->p)
isect(x, erase(y));
}
i64 query(i64 x) {
// assert(!empty());
if (empty()) return -inf;
auto l = *lower_bound(x);
return l.k * x + l.m;
}
};
const int MAXN = 1e5 + 10;
const i64 INF = 1e18;
int N, M, S, T;
i64 H[MAXN], f[3][MAXN];
vector<int> G[MAXN];
void dijkstra(int st, int t) {
for (int i = 1; i <= N; i ++) f[t][i] = INF;
f[t][st] = 0;
priority_queue<pair<i64, int>> pq; pq.push(mp(0, st));
while (!pq.empty()) {
auto [d, u] = pq.top(); pq.pop();
if (f[t][u] != -d) continue;
for (auto v : G[u]) {
i64 add = (H[u] - H[v]) * (H[u] - H[v]);
if (f[t][v] > f[t][u] + add) {
f[t][v] = f[t][u] + add;
pq.push(mp(-f[t][v], v));
}
}
}
// for (int i = 1; i <= N; i ++) {
// cout << t << " " << f[t][i] << "\n";
// }
}
void Solve(void) {
cin >> N >> M >> S >> T;
for (int i = 1; i <= N; i ++) cin >> H[i];
for (int i = 1; i <= M; i ++) {
int u, v; cin >> u >> v;
G[u].pb(v);
G[v].pb(u);
} dijkstra(S, 0); dijkstra(T, 1);
long double ans = INF;
for (int u = 1; u <= N; u ++) {
ans = min(ans, (long double)(f[0][u] + f[1][u]));
LineContainer convex;
for (auto v : G[u]) {
convex.add(2 * H[v], -(2 * f[0][v] + H[v] * H[v]));
}
for (auto v : G[u]) {
long double cur = convex.query(H[v]);
// cout << u << " " << v << " " << cur << " " << 2 * f[1][v] << "\n";
cur = (-cur + 2 * f[1][v] + H[v] * H[v])/2;
ans = min(ans, cur);
// cout << u << " " << v << " " << cur << " " << f[1][v] << "\n";
}
}
cout << ans << "\n";
}
signed main() {
ios_base::sync_with_stdio(false); cin.tie(0);
cout << fixed << setprecision(10);
int Tests = 1; // cin >> Tests;
while (Tests --) {
Solve();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 5880kb
input:
5 6 1 3 5 100 8 2 10 1 2 2 3 2 5 1 4 4 5 3 5
output:
4.5000000000
result:
ok found '4.5000000', expected '4.5000000', error '0.0000000'
Test #2:
score: 0
Accepted
time: 1ms
memory: 7936kb
input:
5 5 1 5 1 2 10 10 4 1 2 2 3 2 4 3 5 4 5
output:
3.0000000000
result:
ok found '3.0000000', expected '3.0000000', error '0.0000000'
Test #3:
score: 0
Accepted
time: 0ms
memory: 5888kb
input:
5 4 1 4 8 8 8 8 100 1 2 2 3 3 4 4 5
output:
0.0000000000
result:
ok found '0.0000000', expected '0.0000000', error '-0.0000000'
Test #4:
score: -100
Wrong Answer
time: 1ms
memory: 8036kb
input:
2 1 1 2 0 100000 1 2
output:
10000000000.0000000000
result:
wrong answer 1st numbers differ - expected: '0.0000000', found: '10000000000.0000000', error = '10000000000.0000000'