Pagini recente » Cod sursa (job #111376) | Cod sursa (job #297834) | Rating Nicholas David Cantar Gogitidze (nicholascantar) | Cod sursa (job #7134) | Cod sursa (job #1536411)
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <climits>
#include <cstdlib>
#define NODE(n) (n>>10)
#define COST(n) (n&1023)
class tipus
{
int sorszam, kulcs;
public:
tipus (int s, int k): sorszam(s), kulcs(k) {}
inline int key() {return kulcs;}
inline int num() {return sorszam;}
inline void set_key (int k) {kulcs = k;}
};
template <typename elem_t>
class heap
{
std::vector<int> pos;
std::vector<elem_t> x;
bool leaf (unsigned p)
{
if (p <= (x.size()-1)/2) return false;
return true;
}
void upheap (unsigned currentpos)
{
while (x[currentpos].key() < x[currentpos/2].key()) {
std::swap (x[currentpos], x[currentpos/2]);
pos[currentpos] = currentpos/2;
pos[currentpos/2] = currentpos;
currentpos /= 2;
}
}
void downheap (unsigned currentpos)
{
unsigned minpos;
int k1, k2;
while (not leaf (currentpos) && currentpos != 0) {
if (currentpos*2 == x.size()-1) {
if (x[currentpos].key() > x[currentpos*2].key()) {
std::swap (x[currentpos], x[currentpos*2]);
pos[currentpos] = currentpos*2;
pos[currentpos*2] = currentpos;
currentpos *= 2;
}
continue;
}
k1 = x[currentpos*2].key();
k2 = x[currentpos*2+1].key();
minpos = k1;
if (k2 < k1) minpos = k2;
if (x[minpos].key() < x[currentpos].key()) {
std::swap (x[minpos], x[currentpos]);
pos[currentpos] = minpos;
pos[minpos] = currentpos;
currentpos = minpos;
}
}
}
public:
heap (unsigned n): pos(n, -1) {}
~heap () {pos.clear(); x.clear();}
void push (elem_t elem)
{
x.push_back (elem);
unsigned currentpos = x.size()-1;
pos[elem.num()] = currentpos;
upheap (currentpos);
}
int min ()
{
return x[0].num();
}
unsigned size ()
{
return x.size();
}
bool exists (unsigned p)
{
if (pos[p] == -1) return false;
return true;
}
void pop ()
{
pos[x[0].num()] = -1;
x[0] = x.back();
pos[x[0].num()] = 0;
x.pop_back();
downheap (0);
}
void decrease_key (int node, int val)
{
x[pos[node]].set_key(val);
upheap (val);
}
};
std::ifstream in ("dijkstra.in");
std::ofstream out ("dijkstra.out");
int n, m;
std::vector< std::list<int> > x;
std::vector<int> path;
void dijkstra (int node)
{
path[node] = 0;
heap<tipus> Min (n+1);
Min.push (tipus(node, 0));
int pos, newlen;
std::list<int>::iterator i;
while (Min.size()) {
pos = Min.min();
Min.pop();
for (i=x[pos].begin(); i!=x[pos].end(); i++) {
newlen = path[pos] + COST(*i);
if (newlen < path[NODE(*i)]) {
path[NODE(*i)] = newlen;
if (Min.exists(NODE(*i))) Min.decrease_key (NODE(*i), newlen);
else Min.push (tipus(NODE(*i), newlen));
}
}
}
}
int main()
{
in >> n >> m;
x.resize (n+1);
path.resize (n+1, INT_MAX);
int a, b, c, i;
for (i=0; i<m; i++) {
in >> a >> b >> c;
x[a].push_back ((b << 10) + c);
}
dijkstra (1);
for (i=2; i<=n; i++) {
if (path[i] != INT_MAX) out << path[i] << " ";
else out << "0 ";
}
exit (0);
}