Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Слава Україні, Героям слава
- #include <bits/stdc++.h>
- using namespace std;
- const int N = 1e5 + 7;
- struct line {
- long long b, m;
- };
- int nh, pos;
- line hull[N], v[N];
- pair<long long, int> tmp[N];
- bool check(line s, line t, line u) {
- return (s.b - t.b) * (u.m - s.m) < (s.b - u.b) * (t.m - s.m);
- }
- void update(line s) {
- while(nh >= 2 and !check(hull[nh - 2], hull[nh - 1], s)) {
- nh--;
- }
- hull[nh++] = s;
- }
- long long eval(int id, long long x) {
- return hull[id].b + hull[id].m * x;
- }
- long long query(long long x) {
- while(pos + 1 < nh and eval(pos, x) < eval(pos + 1, x)) {
- pos++;
- }
- return -eval(pos, x);
- }
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, m, s, t;
- cin >> n >> m >> s >> t;
- vector<long long> h(n + 1);
- vector<vector<int>> adj(n + 1);
- for(int i = 1; i <= n; i++) {
- cin >> h[i];
- h[i] <<= 1;
- }
- bool foi = false;
- for(int i = 0; i < m; i++) {
- int a, b;
- cin >> a >> b;
- adj[a].push_back(b);
- adj[b].push_back(a);
- if((a == s and b == t) or (a == t and b == s)) {
- foi = true;
- }
- }
- if(foi) {
- cout << 0 << "\n";
- return 0;
- }
- vector<vector<long long>> dist(2, vector<long long>(n + 1, LLONG_MAX));
- priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<pair<long long, int>>> pq;
- dist[0][s] = dist[1][t] = 0;
- pq.push({0, s});
- while(!pq.empty()) {
- auto p = pq.top(); pq.pop();
- for(auto e : adj[p.second]) {
- if(dist[0][e] > p.first + (h[e] - h[p.second]) * (h[e] - h[p.second])) {
- dist[0][e] = p.first + (h[e] - h[p.second]) * (h[e] - h[p.second]);
- pq.push({dist[0][e], e});
- }
- }
- }
- pq.push({0, t});
- while(!pq.empty()) {
- auto p = pq.top(); pq.pop();
- for(auto e : adj[p.second]) {
- if(dist[1][e] > p.first + (h[e] - h[p.second]) * (h[e] - h[p.second])) {
- dist[1][e] = p.first + (h[e] - h[p.second]) * (h[e] - h[p.second]);
- pq.push({dist[1][e], e});
- }
- }
- }
- long long ans = LLONG_MAX;
- int sz = 0;
- for(int i = 1; i <= n; i++) {
- if(adj[i].size() == 1 or i == s or i == t) {
- continue;
- }
- nh = pos = sz = 0;
- for(auto e : adj[i]) {
- v[sz] = {-h[e] * h[e] / 2 - dist[0][e], h[e]};
- tmp[sz++] = {h[e], e};
- }
- sort(v, v + sz, [](line s, line t) {
- return (s.m == t.m) ? (s.b < t.b) : (s.m < t.m);
- });
- sort(tmp, tmp + sz);
- for(int i = 0; i < sz; i++) {
- update(v[i]);
- }
- for(int i = 0; i < sz; i++) {
- long long cur = query(tmp[i].first) + dist[1][tmp[i].second] + tmp[i].first * tmp[i].first / 2;
- ans = min(ans, cur);
- }
- }
- cout << ans / 4 << (ans % 4 == 2 ? ".5\n" : "\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement