結果
| 問題 |
No.1065 電柱 / Pole (Easy)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-05-29 21:37:06 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 263 ms / 2,000 ms |
| コード長 | 22,957 bytes |
| コンパイル時間 | 2,727 ms |
| コンパイル使用メモリ | 209,756 KB |
| 最終ジャッジ日時 | 2025-01-10 16:41:25 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 46 |
コンパイルメッセージ
main.cpp:70:24: warning: ‘template<class _Category, class _Tp, class _Distance, class _Pointer, class _Reference> struct std::iterator’ is deprecated [-Wdeprecated-declarations]
70 | class NumberIterator : iterator<forward_iterator_tag, int> {
| ^~~~~~~~
In file included from /usr/include/c++/13/bits/stl_algobase.h:65,
from /usr/include/c++/13/algorithm:60,
from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:51,
from main.cpp:11:
/usr/include/c++/13/bits/stl_iterator_base_types.h:127:34: note: declared here
127 | struct _GLIBCXX17_DEPRECATED iterator
| ^~~~~~~~
ソースコード
/**
* code generated by JHelper
* More info: https://github.com/AlexeyDmitriev/JHelper
* @author Egor Kulikov
*/
#include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(), (v).end()
using ll = long long;
using ull = unsigned long long;
using li = __int128;
using uli = unsigned __int128;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;
void doReplace() {
}
template <typename T, typename U, typename...Vs>
void doReplace(T& t, const U& u, Vs&& ...vs) {
t = u;
doReplace(vs...);
}
template <typename T, typename...Us>
T minim(T& was, const T& cand, Us&& ...us) {
if (was > cand) {
was = cand;
doReplace(us...);
}
return was;
}
template <typename T, typename...Us>
T maxim(T& was, const T& cand, Us&& ...us) {
if (was < cand) {
was = cand;
doReplace(us...);
}
return was;
}
template <typename D>
D dPower(D base, ll exponent) {
if (exponent < 0) {
return dPower(1 / base, -exponent);
}
if (exponent == 0) {
return 1;
}
if ((exponent & 1) == 1) {
return dPower(base, exponent - 1) * base;
} else {
D res = dPower(base, exponent >> 1);
return res * res;
}
}
class NumberIterator : iterator<forward_iterator_tag, int> {
public:
int v;
NumberIterator(int v) : v(v) {}
operator int&() { return v; }
int operator*() { return v; }
};
class range : pii {
public:
range(int begin, int end) : pii(begin, max(begin, end)) {}
range(int n) : pii(0, max(0, n)) {}
NumberIterator begin() {
return first;
}
NumberIterator end() {
return second;
}
};
template <typename T>
class arr {
T* b;
int n;
void allocate(int sz) {
#ifdef LOCAL
if (sz < 0) {
throw "bad alloc";
}
#endif
n = sz;
if (sz > 0) {
b = (T*) (::operator new(sz * sizeof(T)));
} else {
b = nullptr;
}
}
public:
arr(int n = 0) {
allocate(n);
#ifdef LOCAL
view();
#endif
}
arr(int n, const T& init) {
allocate(n);
for (int i : range(n)) {
::new((void*) (b + i)) T(init);
}
#ifdef LOCAL
view();
#endif
}
arr(initializer_list<T> l) : arr(l.size()) {
if (n > 0) {
memcpy(b, l.begin(), n * sizeof(T));
}
}
arr(T* b, int n) : arr(b, b + n) {}
arr(T* b, T* e) : b(b), n(e - b) {}
int size() const {
return n;
}
T* begin() {
return b;
}
const T* begin() const {
return b;
}
T* end() {
return b + n;
}
const T* end() const {
return b + n;
}
arr<T> clone() const {
arr<T> res(n);
copy(b, b + n, res.begin());
return res;
}
T& operator[](int at) {
#ifdef LOCAL
if (at < 0 || at >= n) {
throw "Out of bounds";
}
#endif
return b[at];
}
const T& operator[](int at) const {
#ifdef LOCAL
if (at < 0 || at >= n) {
throw "Out of bounds";
}
#endif
return b[at];
}
bool operator==(const arr& other) const {
if (n != other.n) {
return false;
}
for (int i : range(n)) {
if (b[i] != other.b[i]) {
return false;
}
}
return true;
}
vector<T> view() {
return vector<T>(b, b + min(n, 50));
}
};
typedef arr<int> arri;
void decreaseByOne() {}
template <typename T, class...Vs>
void decreaseByOne(arr<T>& array, Vs& ...vs) {
int n = array.size();
for (int i : range(n)) {
array[i]--;
}
decreaseByOne(vs...);
}
template <typename T, typename U>
void decreaseByOne(arr<pair<T, U>>& v) {
for (auto& p : v) {
p.first--;
p.second--;
}
}
template <typename T>
class arr2d {
T* b;
int d1;
int d2;
int sz;
void allocate(int n) {
#ifdef LOCAL
if (n < 0) {
throw "bad alloc";
}
#endif
if (n > 0) {
b = (T*) (::operator new(n * sizeof(T)));
} else {
b = nullptr;
}
}
public:
arr2d(int d1 = 0, int d2 = 0) : d1(d1), d2(d2), sz(d1 * d2) {
#ifdef LOCAL
if (d1 < 0 || d2 < 0) {
throw "bad alloc";
}
#endif
allocate(sz);
#ifdef LOCAL
view();
#endif
}
arr2d(int d1, int d2, const T& init) : d1(d1), d2(d2), sz(d1 * d2) {
#ifdef LOCAL
if (d1 < 0 || d2 < 0) {
throw "bad alloc";
}
#endif
allocate(sz);
for (int i : range(sz)) {
::new((void*) (b + i)) T(init);
}
#ifdef LOCAL
view();
#endif
}
arr2d(T* b, int d1, int d2) : b(b), d1(d1), d2(d2), sz(d1 * d2) {}
int size() const {
return sz;
}
int dim1() const {
return d1;
}
int dim2() const {
return d2;
}
T* begin() {
return b;
}
T* end() {
return b + sz;
}
T& operator()(int i1, int i2) {
#ifdef LOCAL
if (i1 < 0 || i1 >= d1 || i2 < 0 || i2 >= d2) {
throw "Out of bounds";
}
#endif
return b[i1 * d2 + i2];
}
const T& operator()(int i1, int i2) const {
#ifdef LOCAL
if (i1 < 0 || i1 >= d1 || i2 < 0 || i2 >= d2) {
throw "Out of bounds";
}
#endif
return b[i1 * d2 + i2];
}
T& operator[](const pii& p) {
return operator()(p.first, p.second);
}
const T& operator[](const pii& p) const {
return operator()(p.first, p.second);
}
arr<T> operator[](int at) {
#ifdef LOCAL
if (at < 0 || at >= d1) {
throw "Out of bounds";
}
#endif
return arr<T>(b + at * d2, d2);
}
vector<vector<T>> view() {
vector<vector<T>> res(min(d1, 50));
for (int i : range(res.size())) {
res[i] = (*this)[i].view();
}
return res;
}
arr2d<T> clone() {
arr2d<T> res(d1, d2);
copy(b, b + sz, res.b);
return res;
}
};
inline bool isWhitespace(int c) {
return isspace(c) || c == EOF;
}
class Input {
private:
bool exhausted = false;
int bufSize = 4096;
char* buf = new char[bufSize];
int bufRead = 0;
int bufAt = 0;
public:
inline int get() {
if (exhausted) {
#ifdef LOCAL
throw "Input exhausted";
#endif
return EOF;
}
if (bufRead == bufAt) {
bufRead = fread(buf, sizeof(char), bufSize, stdin);
bufAt = 0;
}
if (bufRead == bufAt) {
exhausted = true;
return EOF;
}
return buf[bufAt++];
}
private:
template <typename T>
inline T readInteger() {
int c = skipWhitespace();
int sgn = 1;
if (c == '-') {
sgn = -1;
c = get();
}
T res = 0;
do {
if (!isdigit(c)) {
#ifdef LOCAL
throw "Number format error";
#endif
return sgn * res;
}
res *= 10;
res += c - '0';
c = get();
} while (!isWhitespace(c));
return res * sgn;
}
void initArrays(int) {}
template <typename T, class...Vs>
void initArrays(int n, arr<T>& array, Vs& ...vs) {
array = arr<T>(n, T());
initArrays(n, vs...);
}
template <typename T, class...Vs>
void initArrays(int n, vector<T>&, Vs& ...vs) {
initArrays(n, vs...);
}
void readImpl(int) {}
template <typename T, class...Vs>
void readImpl(int i, arr<T>& arr, Vs& ...vs) {
arr[i] = readType<T>();
readImpl(i, vs...);
}
template <typename T, class...Vs>
void readImpl(int i, vector<T>& arr, Vs& ...vs) {
arr.push_back(readType<T>());
readImpl(i, vs...);
}
public:
inline int skipWhitespace() {
int c;
while (isWhitespace(c = get()) && c != EOF);
return c;
}
inline int readInt() {
return readInteger<int>();
}
inline ll readLong() {
return readInteger<ll>();
}
string readString() {
int c = skipWhitespace();
if (c == EOF) {
#ifdef LOCAL
throw "Input exhausted";
#endif
return "";
}
string res;
do {
res.push_back(c);
} while (!isWhitespace(c = get()));
return res;
}
arri readIntArray(int size) {
return readArray<int>(size);
}
arr<ll> readLongArray(int size) {
return readArray<ll>(size);
}
arr<double> readDoubleArray(int size) {
return readArray<double>(size);
}
arr<string> readStringArray(int size) {
return readArray<string>(size);
}
arr<char> readCharArray(int size) {
return readArray<char>(size);
}
template <typename T>
T readType() {
throw "Operation not supported";
}
template <typename U, typename V>
pair<U, V> readType() {
U first = readType<U>();
V second = readType<V>();
return make_pair(first, second);
}
template <typename T>
arr<T> readArray(int n) {
arr<T> res(n, T());
for (int i : range(n)) {
res[i] = readType<T>();
}
return res;
}
template <class...Vs>
void readArrays(int n, Vs& ...vs) {
initArrays(n, vs...);
for (int i : range(n)) {
readImpl(i, vs...);
}
}
template <typename U, typename V>
arr<pair<U, V>> readArray(int n) {
arr<pair<U, V>> res(n);
for (int i : range(n)) {
res[i] = readType<U, V>();
}
return res;
}
template <typename T>
arr2d<T> readTable(int rows, int cols) {
arr2d<T> result(rows, cols);
for (int i : range(rows)) {
for (int j : range(cols)) {
result(i, j) = readType<T>();
}
}
return result;
}
arr2d<int> readIntTable(int rows, int cols) {
return readTable<int>(rows, cols);
}
arr2d<char> readCharTable(int rows, int cols) {
return readTable<char>(rows, cols);
}
string readLine() {
int c = get();
if (c == EOF) {
#ifdef LOCAL
throw "Input exhausted";
#endif
return "";
}
string res;
do {
res.push_back(c);
c = get();
} while (c != '\n' && c != '\r' && c != EOF);
return res;
}
inline double readDouble() {
int c = skipWhitespace();
int sgn = 1;
if (c == '-') {
sgn = -1;
c = get();
}
double res = 0;
do {
if (tolower(c) == 'e') {
return sgn * res * dPower(double(10), readInt());
}
if (!isdigit(c)) {
#ifdef LOCAL
throw "Number format error";
#endif
return sgn * res;
}
res *= 10;
res += c - '0';
c = get();
} while (!isWhitespace(c) && c != '.');
if (c == '.') {
double add = 0;
int length = 0;
c = get();
do {
if (tolower(c) == 'e') {
return sgn * (res + add * dPower(double(10), -length)) * dPower(double(10), readInt());
}
if (!isdigit(c)) {
#ifdef LOCAL
throw "Number format error";
#endif
res += add * dPower(10, -length);
return res * sgn;
}
add *= 10;
add += c - '0';
length++;
c = get();
} while (!isWhitespace(c));
res += add * dPower(double(10), -length);
}
return res * sgn;
}
inline char readChar() {
int c = skipWhitespace();
if (c == EOF) {
#ifdef LOCAL
throw "Input exhausted";
#endif
return 0;
}
return c;
}
inline bool isExhausted() { return exhausted; }
inline void setBufSize(int newBufSize) {
if (newBufSize > bufSize) {
char* newBuf = new char[newBufSize];
memcpy(newBuf, buf, bufSize);
buf = newBuf;
}
bufSize = newBufSize;
}
};
template <>
inline double Input::readType() {
return readDouble();
}
template <>
inline int Input::readType() {
return readInt();
}
template <>
inline ll Input::readType() {
return readLong();
}
template <>
inline char Input::readType() {
return readChar();
}
template <>
inline string Input::readType() {
return readString();
}
Input in;
class Output {
private:
ostream* out;
template <typename T>
inline void printSingle(const T& value) {
*out << value;
}
template <typename T>
void printSingle(const vector<T>& array) {
size_t n = array.size();
for (int i : range(n)) {
*out << array[i];
if (i + 1 != n) {
*out << ' ';
}
}
}
template <typename T>
void printSingle(const arr<T>& array) {
int n = array.size();
for (int i : range(n)) {
*out << array[i];
if (i + 1 != n) {
*out << ' ';
}
}
}
template <typename T>
void printSingle(const arr2d<T>& array) {
size_t n = array.dim1();
size_t m = array.dim2();
for (int i : range(n)) {
for (int j : range(m)) {
*out << array(i, j);
if (j + 1 != m) {
*out << ' ';
}
}
if (i + 1 != n) {
*out << '\n';
}
}
}
template <typename T, typename U>
inline void printSingle(const pair<T, U>& value) {
out << value.first << ' ' << value.second;
}
public:
bool autoflush;
Output(ostream& out, bool autoflush) : out(&out), autoflush(autoflush) {
setPrecision(20);
}
void setOut(ostream& nOut) {
out = &nOut;
setPrecision(20);
}
inline void print() {}
template <typename T, typename...Targs>
inline void print(const T& first, const Targs... args) {
printSingle(first);
if (sizeof...(args) != 0) {
*out << ' ';
print(args...);
}
if (autoflush) {
flush();
}
}
template <typename...Targs>
inline void printLine(const Targs... args) {
print(args...);
*out << '\n';
if (autoflush) {
flush();
}
}
inline void flush() {
out->flush();
}
inline void setPrecision(int digs) {
*out << fixed << setprecision(digs);
}
};
Output out(cout, false);
Output err(cerr, true);
template <class Edge>
class Graph {
public:
int vertexCount;
int edgeCount = 0;
private:
vector<vector<Edge>> edges;
public:
Graph(int vertexCount) : vertexCount(vertexCount), edges(vertexCount, vector<Edge>()) {}
template <typename...Ts>
Edge& addEdge(int from, int to, Ts... args) {
#ifdef LOCAL
if (from < 0 || to < 0 || from >= vertexCount || to >= vertexCount) {
throw "Out of bounds";
}
#endif
edges[from].emplace_back(to, edgeCount, args...);
Edge& direct = edges[from].back();
int directId = edges[from].size() - 1;
if (Edge::reversable) {
edges[to].push_back(direct.reverseEdge(from));
Edge& reverse = edges[to].back();
int revId = edges[to].size() - 1;
direct.setReverseId(revId);
reverse.setReverseId(directId);
}
edgeCount++;
return direct;
}
vector<Edge>& operator[](int at) {
return edges[at];
}
void addVertices(int count) {
vertexCount += count;
edges.resize(vertexCount);
}
void clear() {
edgeCount = 0;
for (int i : range(vertexCount)) {
edges[i].clear();
}
}
};
class BaseEdge {
public:
const static bool reversable = false;
int to;
int id;
BaseEdge(int to, int id) : to(to), id(id) {
}
BaseEdge reverseEdge(int) {
throw "Unsupported operation exception";
}
void setReverseId(int) {
throw "Unsupported operation exception";
}
};
class BiEdge : public BaseEdge {
public:
const static bool reversable = true;
int rev;
BiEdge(int to, int id) : BaseEdge(to, id) {
}
void setReverseId(int revId) {
rev = revId;
}
BiEdge reverseEdge(int from) {
return BiEdge(from, id);
}
BiEdge& reverseEdge(Graph<BiEdge>& graph) {
return graph[to][rev];
}
};
template <typename W>
class BiWeightedEdge : public BiEdge {
public:
const static bool reversable = true;
W weight;
BiWeightedEdge(int to, int id, W weight) : BiEdge(to, id), weight(weight) {
}
BiWeightedEdge reverseEdge(int from) {
return BiWeightedEdge(from, id, weight);
}
BiWeightedEdge<W>& reverseEdge(Graph<BiWeightedEdge<W>>& graph) {
return graph[to][rev];
}
};
class IndexedHeap {
arri heap;
arri pos;
int sz = 0;
function<bool(int, int)> cmp;
void swap(int i, int j) {
std::swap(heap[i], heap[j]);
std::swap(pos[heap[i]], pos[heap[j]]);
}
public:
IndexedHeap(int capacity = 0, const function<bool(int, int)> cmp = less<int>()) : heap(arri(capacity)),
pos(arri(capacity, -1)),
cmp(cmp) {}
int* begin() {
return heap.begin();
}
int* end() {
return heap.begin() + sz;
}
const int* begin() const {
return heap.begin();
}
const int* end() const {
return heap.begin() + sz;
}
int size() const {
return sz;
}
bool empty() const {
return sz == 0;
}
void siftUp(int index) {
#ifdef LOCAL
if (index < 0 || index >= sz) {
throw "Out of bounds";
}
#endif
int val = heap[index];
while (index) {
int parent = (index - 1) >> 1;
int parVal = heap[parent];
if (!cmp(val, parVal)) {
heap[index] = val;
pos[val] = index;
return;
}
heap[index] = parVal;
pos[parVal] = index;
index = parent;
}
heap[0] = val;
pos[val] = 0;
}
void siftDown(int index) {
#ifdef LOCAL
if (index < 0 || index >= sz) {
throw "Out of bounds";
}
#endif
while (true) {
int child = (index << 1) + 1;
if (child >= sz) {
return;
}
if (child + 1 < sz && cmp(heap[child + 1], heap[child])) {
child++;
}
if (!cmp(heap[child], heap[index])) {
return;
}
swap(index, child);
index = child;
}
}
int operator[](int index) const {
#ifdef LOCAL
if (index < 0 || index >= sz) {
throw "Out of bounds";
}
#endif
return heap[index];
}
void push(int element) {
#ifdef LOCAL
if (element < 0 || element >= pos.size() || pos[element] != -1) {
throw "Out of bounds";
}
#endif
heap[sz] = element;
pos[element] = sz;
siftUp(sz++);
}
int at(int element) const {
#ifdef LOCAL
if (element < 0 || element >= pos.size()) {
throw "Out of bounds";
}
#endif
return pos[element];
}
int top() const {
#ifdef LOCAL
if (sz == 0) {
throw "Out of bounds";
}
#endif
return heap[0];
}
int pop() {
#ifdef LOCAL
if (sz == 0) {
throw "Out of bounds";
}
#endif
int res = heap[0];
pos[res] = -1;
if (sz == 1) {
sz = 0;
return res;
}
heap[0] = heap[--sz];
pos[heap[0]] = 0;
siftDown(0);
return res;
}
bool erase(int element) {
#ifdef LOCAL
if (element < 0 || element >= pos.size()) {
throw "Out of bounds";
}
#endif
int index = pos[element];
if (index == -1) {
return false;
}
pos[element] = -1;
if (index == sz - 1) {
sz--;
return true;
}
heap[index] = heap[--sz];
pos[heap[index]] = index;
siftDown(index);
siftUp(index);
return true;
}
void clear() {
sz = 0;
fill(all(pos), -1);
}
};
template <class Edge, typename W>
arr<pair<W, pair<int, Edge*>>> dijkstra(Graph<Edge>& graph, int source) {
int n = graph.vertexCount;
arr<pair<W, pair<int, Edge*>>> res(n, {numeric_limits<W>::max(), make_pair(-1, nullptr)});
res[source].first = 0;
IndexedHeap heap(n, [&](int a, int b) -> bool {
return res[a].first < res[b].first;
});
heap.push(source);
while (!heap.empty()) {
int cur = heap.pop();
for (auto& e : graph[cur]) {
int next = e.to;
W total = e.weight + res[cur].first;
if (res[next].first > total) {
res[next].first = total;
int at = heap.at(next);
if (at == -1) {
heap.push(next);
} else {
heap.siftUp(at);
}
res[next].second = {cur, &e};
}
}
}
return res;
}
class c {
public:
void solve() {
int n = in.readInt();
int m = in.readInt();
int from = in.readInt() - 1;
int to = in.readInt() - 1;
arri x, y;
in.readArrays(n, x, y);
arri u, v;
in.readArrays(m, u, v);
decreaseByOne(u, v);
using Edge = BiWeightedEdge<ld>;
Graph<Edge> graph(n);
for (int i : range(m)) {
graph.addEdge(u[i], v[i], hypot(x[u[i]] - x[v[i]], y[u[i]] - y[v[i]]));
}
out.printLine(dijkstra<Edge, ld>(graph, from)[to].first);
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
#ifdef LOCAL_RELEASE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
auto time = clock();
#endif
c solver;
solver.solve();
fflush(stdout);
#ifdef LOCAL_RELEASE
cerr << clock() - time << endl;
#endif
return 0;
}