Cod sursa(job #2217958)

Utilizator claudiu.gatinaFMI Claudiu Gatina claudiu.gatina Data 2 iulie 2018 18:50:50
Problema Algoritmul lui Dijkstra Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.78 kb
#include <iostream>
#include <cstdio>
#include <vector>

#define MAXINT 2147483647

using namespace std;

struct Edge
{
  int cost;
  int target;
  Edge(int t, int c)
  {
    cost = c;
    target = t;
  }
};

class EdgeHeap
{
  vector<Edge> m_heap;
public:
  EdgeHeap()
  {
    m_heap.push_back(Edge(0, -1));
  }

  bool empty()
  {
    return m_heap.size() == 1;
  }

  void insert(const Edge& edge)
  {
    m_heap.push_back(edge);
    int indice = m_heap.size() - 1;
    while(m_heap[indice / 2].cost > m_heap[indice].cost)
    {
      Edge aux(m_heap[indice]);
      m_heap[indice] = m_heap[indice / 2];
      m_heap[indice / 2] = aux;

      indice /= 2;
    }
  }

  Edge decapitate()
  {
    const Edge result = m_heap[1];
    m_heap[1] = m_heap[m_heap.size() - 1]; // take last element
    m_heap.pop_back();
    int indice = 1;
    while(2 * indice + 1 < m_heap.size() && 
      ((m_heap[indice].cost > m_heap[2 * indice].cost || m_heap[indice].cost > m_heap[2 * indice + 1].cost)))
    {
      indice = (m_heap[2 * indice].cost < m_heap[2 * indice + 1].cost) ? (2 * indice) : (2 * indice + 1);
      const Edge aux(m_heap[indice]);
      m_heap[indice] = m_heap[indice / 2];
      m_heap[indice / 2] = aux;
    }
    if(2 * indice < m_heap.size())
      if(m_heap[indice].cost > m_heap[2 * indice].cost)
      {
        indice *= 2;
        const Edge aux(m_heap[indice]);
        m_heap[indice] = m_heap[indice / 2];
        m_heap[indice / 2] = aux;
      }
    return result;
  }
};

int main()
{
  freopen("dijkstra.in", "r", stdin);
  freopen("dijkstra.out", "w", stdout);
  int n, m;
  cin >> n >> m;
  vector<Edge> edges[50001];
  for(int i = 1; i <= m; ++i)
  {
    int firstNode, secondNode, cost;
    cin >> firstNode >> secondNode >> cost;
    edges[firstNode].push_back(Edge(secondNode, cost));
    edges[secondNode].push_back(Edge(firstNode, cost));
  }
  
  EdgeHeap priorityQueue;
  for(int i = 0; i < edges[1].size(); ++i)
    priorityQueue.insert(edges[1][i]);
  vector<int> visited(n + 1, 0);
  vector<int> cost(n + 1, MAXINT);
  cost[1] = 0;
  visited[1] = 1;
  while(!priorityQueue.empty())
  {
    Edge nextEdge = priorityQueue.decapitate();
    int nextNode = nextEdge.target;
    if(!visited[nextNode])
    {
      cost[nextNode] = nextEdge.cost;
      visited[nextNode] = 1;
      for(int i = 0; i < edges[nextNode].size(); ++i)
      {
        int targetNode = edges[nextNode][i].target;
        if(!visited[targetNode])
        {
          priorityQueue.insert(Edge(targetNode, cost[nextNode] + edges[nextNode][i].cost));
        }
      }
    }
  }
  for(int i = 2; i <= n; ++i)
  {
    if(cost[i] == MAXINT)
      cout << "0 ";
    else
      cout << cost[i] << ' ';
  }
  return 0;
}