Pagini recente » Cod sursa (job #3223480) | Cod sursa (job #2164408) | Cod sursa (job #703540) | Cod sursa (job #1879114) | Cod sursa (job #2498909)
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
class parser {
public:
inline parser() {
/// default c-tor
}
inline parser(const char* file_name) {
int fd = open(file_name, O_RDONLY);
index &= 0;
fstat(fd, &sb);
buffer = (char*)mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
close(fd);
}
template <typename T>
inline parser& operator >> (T& n) {
n &= 0;
for (; buffer[index] < '0' or buffer[index] > '9'; ++index);
#ifdef SIGNED
sign &= 0;
sign = (buffer[(index ? index - 1 : 0)] == '-');
#endif
for (; '0' <= buffer[index] and buffer[index] <= '9'; ++index)
n = (n << 3) + (n << 1) + buffer[index] - '0';
#ifdef SIGNED
n ^= ((n ^ -n) & -sign);
#endif
return *this;
}
~parser() {
munmap(buffer, sb.st_size);
}
private:
struct stat sb;
int index;
#ifdef SIGNED
int sign;
#endif
char* buffer;
};
class writer {
public:
writer() {};
writer(const char* file_name) {
output_file.open(file_name, std::ios::out | std::ios::binary);
output_file.sync_with_stdio(false);
index &= 0;
}
template <typename T>
inline writer& operator <<(T target) {
auto inc = [&, this]() mutable {
if (++index == SIZE)
index &= 0,
output_file.write(buffer, SIZE);
};
aux &= 0;
#ifdef SIGNED_WRITE
sign = 1;
if (target < 0)
sign = -1;
#endif // SIGNED_WRITE
if (target == 0) {
buffer[index] = '0';
inc();
return *this;
}
for (; target; target = target / 10)
#ifndef SIGNED_WRITE
nr[aux++] = target % 10 + '0';
#else
nr[aux++] = (sign * target) % 10 + '0';
if (sign == -1)
buffer[index] = '-', inc();
#endif // SIGNED_WRITE
for (; aux; inc())
buffer[index] = nr[--aux];
return *this;
}
inline writer& operator <<(const char* target) {
auto inc = [&, this]() mutable {
if (++index == SIZE)
index &= 0,
output_file.write(buffer, SIZE);
};
aux &= 0;
while (target[aux])
buffer[index] = target[aux++], inc();
return *this;
}
inline void close() {
delete this;
}
~writer() {
output_file.write(buffer, index);
output_file.close();
}
private:
static const int SIZE = 0x200000; ///2MB
int index, aux;
#ifdef SIGNED_WRITE
int sign;
#endif // SIGNED_WRITE
char buffer[SIZE], nr[24];
std::fstream output_file;
};
#define DYNAMIC_ALLOC
template <class _elem, typename compare_by>
class heap {
public:
heap(size_t _size = 1024) : max_size(_size),
current_bound(1) {
storage = new _elem[max_size];
}
heap(const heap<_elem, compare_by>& target) { *this = target; }
heap& operator = (const heap<_elem, compare_by>& target) {
delete[] storage;
max_size = target.max_size;
storage = new _elem[max_size];
for (unsigned i = 0; i < max_size; ++i)
storage[i] = target.storage[i];
current_bound = target.current_bound;
}
[[gnu::pure]] inline bool empty() { return (current_bound == 1); }
[[gnu::pure]] inline _elem top() { return storage[1]; }
[[gnu::pure]] inline _elem last_item() { return storage[0]; }
[[gnu::hot]] inline void add(_elem target) {
storage[current_bound] = target;
sift_up(current_bound);
#ifdef DYNAMIC_ALLOC
if (++current_bound == max_size - 1) {
max_size <<= 1;
auto dummy = (_elem*)realloc(storage, max_size);
storage = dummy;
}
#else
++current_bound;
#endif
}
[[gnu::hot]] inline _elem pop() {
if (empty())
exit(2);
storage[0] = storage[1];
storage[1] = storage[--current_bound];
sift_down(1);
return storage[0];
}
~heap() { delete[] storage; }
private:
[[gnu::hot]] inline void sift_up(unsigned crawler) {
_elem aux = storage[crawler];
while (parent_pos(crawler) && comparator(aux, parent(crawler))) {
storage[crawler] = parent(crawler);
crawler = parent_pos(crawler);
}
storage[crawler] = aux;
}
[[gnu::hot]] inline void sift_down(unsigned crawler) {
_elem aux = storage[crawler];
while (!is_leaf(crawler)) {
if (!comparator(aux, left_son(crawler)) &&
(!comparator(right_son(crawler), left_son(crawler)) ||
right_son_pos(crawler) == current_bound)) {
storage[crawler] = left_son(crawler);
crawler = left_son_pos(crawler);
}
else if (!comparator(aux, right_son(crawler))) {
storage[crawler] = right_son(crawler);
crawler = right_son_pos(crawler);
}
else {
break;
}
}
storage[crawler] = aux;
}
[[gnu::hot, gnu::pure]] inline unsigned right_son_pos(unsigned pos) {
return 1 + (pos << 1);
}
[[gnu::hot, gnu::pure]] inline _elem right_son(unsigned pos) {
return storage[right_son_pos(pos)];
}
[[gnu::hot, gnu::pure]] inline unsigned left_son_pos(unsigned pos) {
return (pos << 1);
}
[[gnu::hot, gnu::pure]] inline _elem left_son(unsigned pos) {
return storage[left_son_pos(pos)];
}
[[gnu::hot, gnu::pure]] inline unsigned parent_pos(unsigned pos) {
return (pos >> 1);
}
[[gnu::hot, gnu::pure]] inline _elem parent(unsigned pos) {
return storage[parent_pos(pos)];
}
[[gnu::hot]] inline bool is_leaf(unsigned pos) {
return !(right_son_pos(pos) < current_bound || left_son_pos(pos) < current_bound);
}
compare_by comparator;
size_t max_size, current_bound;
_elem* storage;
};
constexpr int INF = (1LL << 31) - 1;
struct edge {
int first, second;
};
struct edge_comparator {
inline bool operator ()(const edge& a, const edge& b) {
return a.second < b.second;
}
};
std::vector <edge> graph[50010];
int distance[50010], number_of_nodes;
void dijkstra(int nod) {
heap<edge, edge_comparator> h(50010);
for (int i = 1; i <= number_of_nodes; ++i)
distance[i] = INF;
distance[nod] = 0;
h.add({ nod, 0 });
while (!h.empty()) {
auto current = h.pop();
if (distance[current.first] != current.second) continue;
std::cout << current.first << std::endl;
for (auto i : graph[current.first])
if (distance[i.first] > distance[current.first] + i.second)
distance[i.first] = distance[current.first] + i.second,
h.add({ i.first, distance[i.first] });
}
}
int main() {
parser f("dijkstra.in");
writer t("dijkstra.out");
int x, y, c, m;
f >> number_of_nodes >> m;
for (int i = 0; i < m; ++i)
f >> x >> y >> c,
graph[x].push_back({ y,c });
dijkstra(1);
for (int i = 2; i <= number_of_nodes; ++i)
if (distance[i] == INF) t << "0 ";
else t << distance[i] << " ";
return 0;
}