Advertisement
Algue-Rythme

UVa 12878

Mar 25th, 2017
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.77 KB | None | 0 0
  1. #include <algorithm>
  2. #include <vector>
  3. #include <iostream>
  4. #include <functional>
  5. #include <queue>
  6. #include <set>
  7. #include <array>
  8.  
  9. using namespace std;
  10.  
  11. struct Edge
  12. {
  13.     Edge() {};
  14.     Edge(int _id, int _weight, int _from):
  15.     id(_id), weight(_weight), from(_from) {}
  16.     int id;
  17.     int weight;
  18.     int from;
  19.     bool operator<(const Edge& other) const {
  20.         return weight > other.weight;
  21.     }
  22. };
  23.  
  24. const int NEVER_DISCOVER = -1;
  25. const int INFTY = 1000*1000*1000;
  26.  
  27. const int nbNodesMax = 10*1000 + 1;
  28. array<int, nbNodesMax> closed_set;
  29. array<set<int>, nbNodesMax> comeFrom;
  30. array<bool, nbNodesMax> seen;
  31. using Node = vector<Edge>;
  32. using Graph = array<Node, nbNodesMax>;
  33. Graph graph;
  34.  
  35. int dfs(const Edge& edge) {
  36.     int node = edge.id;
  37.     int seum = edge.weight;
  38.     if (seen[node])
  39.         return seum;
  40.     seen[node] = true;
  41.     for (const auto& edge : graph[node]) {
  42.         if (comeFrom[node].find(edge.from) != end(comeFrom[node])) {
  43.             seum += dfs(edge);
  44.         }
  45.     }
  46.     return seum;
  47. }
  48.  
  49. int
  50. dijkstra(int departure, int arrival)
  51. {
  52.     priority_queue<Edge> openset;
  53.     openset.push(Edge(departure, 0, -1));
  54.  
  55.     for (auto& from : comeFrom)
  56.         from.clear();
  57.  
  58.     closed_set.fill(NEVER_DISCOVER);
  59.  
  60.     while (!openset.empty())
  61.     {
  62.         Edge current = openset.top();
  63.         openset.pop();
  64.  
  65.         if (closed_set[current.id] != NEVER_DISCOVER
  66.             && current.weight > closed_set[current.id]) {
  67.             break ;
  68.         }
  69.  
  70.         if (closed_set[current.id] != NEVER_DISCOVER
  71.             && closed_set[current.id] < current.weight)
  72.             continue ;
  73.         closed_set[current.id] = current.weight;
  74.         comeFrom[current.id].insert(current.from);
  75.  
  76.         for (auto neighbour : graph[current.id]) {
  77.             int newWeight = neighbour.weight + current.weight;
  78.             if (closed_set[neighbour.id] == NEVER_DISCOVER
  79.             || newWeight <= closed_set[neighbour.id]) {
  80.                 closed_set[neighbour.id] = newWeight;
  81.                 Edge edge(neighbour.id, newWeight, neighbour.from);
  82.                 openset.push(edge);
  83.             }
  84.         }
  85.     }
  86.  
  87.     seen.fill(false);
  88.     return 2*dfs(Edge(arrival, 0, -2));
  89. }
  90.  
  91. int main() {
  92.     cin.tie(nullptr);
  93.     ios::sync_with_stdio(false);
  94.  
  95.     int nbNodes, nbEdges;
  96.     while (cin >> nbNodes >> nbEdges) {
  97.         for (auto& node : graph)
  98.             node.clear();
  99.         for (int edge = 0; edge < nbEdges; ++edge)
  100.         {
  101.             int departure, arrival, weight;
  102.             cin >> departure >> arrival >> weight;
  103.             graph[departure].emplace_back(arrival, weight, edge);
  104.             graph[arrival].emplace_back(departure, weight, edge);
  105.         }
  106.  
  107.         cout << dijkstra(0, nbNodes-1) << "\n";
  108.     }
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement