Mai intai trebuie sa te autentifici.
Cod sursa(job #454110)
Utilizator | Data | 11 mai 2010 18:26:16 | |
---|---|---|---|
Problema | Algoritmul lui Dijkstra | Scor | 90 |
Compilator | cpp | Status | done |
Runda | Arhiva educationala | Marime | 2.54 kb |
#include<fstream>
#include<algorithm>
#include<queue>
#include<vector>
#include<list>
#include<set>
#define FIN "dijkstra.in"
#define FOUT "dijkstra.out"
#define INF ~(1<<31)
#define NMAX 50005
#define NIL -1
#define ALB 0
#define GRI 1
#define NEGRU 2
#define FALSE -1
#define Father(x) ((x)>>1)
#define Left(x) ((x)<<1)
#define Right(x) (((x)<<1)+1)
using namespace std;
typedef struct
{
int to;
int cost;
}NODE;
vector<list<NODE> > L;
int N, M, END;
int P[NMAX], D[NMAX], H[NMAX], IN[NMAX];
void read (char *);
void Dijkstra (int);
void init (int);
void heap_create (int);
void heap_insert (int);
int pop_heap ();
void Up (int);
void Down (int);
int main(int argc, char **argv)
{
read (argv[1]);
Dijkstra(1);
FILE *fout = fopen (FOUT, "w");
int i;
for (i = 2; i <= N; ++i)
fprintf(fout, "%d ", D[i] == INF? 0 : D[i]);
fclose (fout);
return 0;
}
void Dijkstra (int source)
{
list<NODE>::iterator i;
END = 0;
init(source);
//`heap_create (N);
H[++END] = source;
while (END)
{
int u = pop_heap ();
for (i = L[u].begin(); i != L[u].end(); ++i)
if (D[i->to] > D[u] + i->cost)
{
D[i->to] = D[u] + i->cost;
P[i->to] = u;
if (IN[i->to] == FALSE)
heap_insert (i->to);
else
Up (IN[i->to]);
}
}
}
void heap_create (int dim)
{
//H.resize(dim+1);
}
void Up (int p)
{
// while (p > 1 && D[H[Father(p)]] > D[value])
while (p > 1 && D[H[Father(p)]] > D[H[p]])
{
IN[H[p]] = Father(p);
IN[H[Father(p)]] = p;
H[p] ^= H[Father(p)];
H[Father(p)] ^= H[p];
H[p] ^= H[Father(p)];
p = Father(p);
}
}
void heap_insert (int value)
{
H[++END] = value;
IN[H[END]] = END;
Up (END);
}
int pop_heap ()
{
int min = H[1];
H[1] = H[END--];
IN[H[1]] = 1;
Down (1);
return min;
}
void Down (int p)
{
int left = Left(p);
int right = Right(p);
int to;
if (D[H[p]] > D[H[left]] && left <= END)
to = left;
else
to = p;
if (D[H[to]] > D[H[right]] && right <= END)
to = right;
if (to != p)
{
IN[H[p]] = to;
IN[H[to]] = p;
H[to] ^= H[p];
H[p] ^= H[to];
H[to] ^= H[p];
Down (to);
}
}
void read (char *file)
{
FILE *fin = fopen (FIN, "r");
int i;
fscanf(fin, "%d%d", &N, &M);
L.resize(N+1);
for (i = 0; i < M; ++i)
{
int from, to, cost;
NODE aux;
fscanf (fin, "%d%d%d", &from, &to, &cost);
aux.to = to;
aux.cost = cost;
L[from].push_back(aux);
}
fclose (fin);
}
void init (int source)
{
int i;
//P.resize (N+1);
//D.resize (N+1);
//IN.resize (N+1);
for (i = 2; i <= N; ++i)
{
P[i] = NIL;
D[i] = INF;
IN[i] = FALSE;
}
P[source] = NIL;
D[source] = 0;
IN[source] = 1;
}