Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <list>
- #include <vector>
- #include <utility>
- class Heap {
- private:
- std::vector<std::pair<size_t, int>> data;
- std::vector<int> vertIndex;
- size_t heapSize = 0;
- void Heapify(std::vector<std::pair<size_t, int>>& A, size_t length, size_t i) {
- size_t l = 2 * i + 1;
- size_t r = 2 * i + 2;
- size_t smallest = i;
- if (l < length && A[l].second < A[smallest].second)
- smallest = l;
- if (r < length && A[r].second < A[smallest].second)
- smallest = r;
- if (smallest != i) {
- std::swap(A[i], A[smallest]);
- std::swap(vertIndex[A[i].first], vertIndex[A[smallest].first]);
- Heapify(A, length, smallest);
- }
- }
- void buildHeap(std::vector<std::pair<size_t, int>> &A, size_t length) {
- for (size_t i = length / 2 - 1; i != (size_t)(-1); --i) {
- Heapify(A, length, i);
- }
- }
- public:
- Heap(size_t size, int vertex = 0) {
- heapSize = size;
- data.resize(size);
- vertIndex.resize(size);
- for (size_t i = 0; i < size; ++i) {
- data[i] = std::pair<size_t, int>(i, vertex);
- vertIndex[i] = i;
- }
- }
- template <class InputIt>
- Heap(InputIt begin, InputIt end) {
- size_t length = end - begin;
- heapSize = length;
- vertIndex.resize(length);
- for (size_t i = 0; i < length; ++i) {
- data.push_back(std::pair<size_t, int>(i, *begin));
- vertIndex[i] = i;
- ++begin;
- }
- buildHeap(data, heapSize);
- }
- Heap(std::initializer_list<int> input) {
- size_t length = input.size();
- heapSize = length;
- vertIndex.resize(length);
- auto begin = input.begin();
- for (size_t i = 0; i < length; ++i) {
- data.push_back(std::pair<size_t, int>(i, *begin));
- vertIndex[i] = i;
- ++begin;
- }
- buildHeap(data, heapSize);
- }
- bool empty() const {
- return heapSize == 0;
- }
- size_t size() const {
- return heapSize;
- }
- size_t top() const {
- return data[0].first;
- }
- void pop() {
- data[0] = data[heapSize - 1];
- vertIndex[data[0].first] = 0;
- --heapSize;
- Heapify(data, heapSize, 0);
- }
- void decrease_key(size_t vert, int key) {
- size_t i = vertIndex[vert];
- data[i].second = key;
- while (i > 0 && data[(i-1)/2].second > data[i].second) {
- std::swap(data[(i-1)/2], data[i]);
- std::swap(vertIndex[data[(i-1)/2].first], vertIndex[data[i].first]);
- i = (i-1)/2;
- }
- }
- };
- const int INF = 2147483647;
- std::vector<int> dijkstra(std::vector<std::list<std::pair<size_t, int>>>& roadGraph,
- int start) {
- size_t size = roadGraph.size();
- std::vector<int> minPathLen(size, INF);
- Heap vertHeap(size, INF);
- vertHeap.decrease_key(start - 1, 0);
- minPathLen[start - 1] = 0;
- while (!vertHeap.empty()) {
- size_t vertex = vertHeap.top();
- vertHeap.pop();
- for (auto vert : roadGraph[vertex]) {
- if (minPathLen[vert.first] > minPathLen[vertex] + vert.second) {
- vertHeap.decrease_key(vert.first, minPathLen[vertex] + vert.second);
- minPathLen[vert.first] = minPathLen[vertex] + vert.second;
- }
- }
- }
- return minPathLen;
- }
- int calculate_min_cost() {
- int buildingsNum, roadsNum;
- std::cin >> buildingsNum >> roadsNum;
- std::vector<std::list<std::pair<size_t, int>>> roadGraph(buildingsNum);
- int buildingA, buildingB;
- for (; roadsNum > 0; --roadsNum) {
- std::cin >> buildingA >> buildingB;
- roadGraph[buildingA - 1].push_back(std::pair<size_t, int>(buildingB - 1, 0));
- roadGraph[buildingB - 1].push_back(std::pair<size_t, int>(buildingA - 1, 0));
- }
- int newRoadsNum, roadPrice;
- std::cin >> newRoadsNum;
- for (; newRoadsNum > 0; --newRoadsNum) {
- std::cin >> buildingA >> buildingB >> roadPrice;
- roadGraph[buildingA - 1].push_back(std::pair<size_t, int>(buildingB - 1, roadPrice));
- roadGraph[buildingB - 1].push_back(std::pair<size_t, int>(buildingA - 1, roadPrice));
- }
- int start, finish;
- std::cin >> start >> finish;
- std::vector<int> minPathlen = dijkstra(roadGraph, start);
- if (minPathlen[finish - 1] == INF) {
- return -1;
- } else {
- return minPathlen[finish - 1];
- }
- }
- int main() {
- int buildingsNum, roadsNum;
- std::cin >> buildingsNum >> roadsNum;
- std::vector<std::list<std::pair<size_t, int>>> roadGraph(buildingsNum);
- int buildingA, buildingB;
- for (; roadsNum > 0; --roadsNum) {
- std::cin >> buildingA >> buildingB;
- roadGraph[buildingA - 1].push_back(std::pair<size_t, int>(buildingB - 1, 0));
- roadGraph[buildingB - 1].push_back(std::pair<size_t, int>(buildingA - 1, 0));
- }
- int newRoadsNum, roadPrice;
- std::cin >> newRoadsNum;
- for (; newRoadsNum > 0; --newRoadsNum) {
- std::cin >> buildingA >> buildingB >> roadPrice;
- roadGraph[buildingA - 1].push_back(std::pair<size_t, int>(buildingB - 1, roadPrice));
- roadGraph[buildingB - 1].push_back(std::pair<size_t, int>(buildingA - 1, roadPrice));
- }
- int start, finish;
- std::cin >> start >> finish;
- std::vector<int> minPathlen = dijkstra(roadGraph, start);
- if (minPathlen[finish - 1] == INF) {
- std::cout << -1;
- } else {
- std::cout << minPathlen[finish - 1];
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement