Pagini recente » Cod sursa (job #2737463) | Cod sursa (job #3291577) | Cod sursa (job #1705367) | Cod sursa (job #3256497) | Cod sursa (job #701012)
Cod sursa(job #701012)
#include<stdio.h>
#include<fstream>
using namespace std;
#include<math.h>
#include<assert.h>
#define MAX 50001
#define INF 1000000000
int dist[MAX];
int nrNodes;
typedef struct FibHeap
{
bool mark;
int degree;
int index;
FibHeap *father,*left,*right,*child;
}FibHeap;
typedef struct graf
{
int nod,et;
graf* next;
}graf;
int N,M;
graf* a[MAX];
FibHeap* Min;
FibHeap* ARB[MAX];
bool T[MAX];
//-------------------------------FIBHEAP----------------------------------------
//returns the upper bound D(n) on the maximum degree of any code in an n-node Fibonacci heap
float D(int n)
{
return ceil(log((float)n));
};
//if fh1 < fh2 then return a value <0, else return a value >=0
int compareNode(FibHeap* fh1, FibHeap* fh2)
{
return dist[fh1->index] - dist[fh2->index];
};
int compareIndex(int index1, int index2)
{
return dist[index1]-dist[index2];
}
FibHeap* createFibHeap(int new_index)
{
FibHeap* H = new FibHeap();
H->mark = false;
H->degree = 0;
H->index = new_index;
H->father = NULL;
H->left = H;
H->right = H;
H->child = NULL;
return H;
};
void insertFibHeap(FibHeap** H, FibHeap* x)
{
x->left = x;
x->right = x;
x->father = NULL;
if((*H) != NULL)
{
x->right = (*H);
x->left = (*H)->left;
(*H)->left->right = x;
(*H)->left = x;
if(compareNode((*H), x) > 0)
(*H) = x;
}
else
(*H) = x;
};
//ATENTION! the pointer to the min node is not refreshed
void FibHeapLink(FibHeap* y, FibHeap* x)
{
// remove y from the root list of H
//y->father must be NULL because y must be in the root list of H
if(y->father != NULL)
{
if(y->father->degree > 1)
y->father->child = y->right;
else
y->father->child = NULL;
y->father->degree--;
y->father = NULL;
}
if(y != y->right)
{
y->right->left = y->left;
y->left->right = y->right;
}
y->left = y;
y->right = y;
//make y a child of x, incrementing x->degree
y->father = x;
if(x->degree == 0)
x->child = y;
else
{
y->right = x->child;
y->left = x->child->left;
x->child->left->right = y;
x->child->left = y;
}
x->degree++;
y->mark = false;
};
void consolidate(FibHeap** H)
{
FibHeap *A[MAX];
float dn = D(nrNodes);
for(int i=0;i<=2*dn;i++)
A[i] = NULL;
FibHeap* aux = (*H);
do
{
FibHeap* aux2 = aux->right;
int deg = aux->degree;
FibHeap* aux3 = aux;
while(A[deg] != NULL)
{
//union 2 trees with the same degree
if(compareNode(aux3,A[deg])>=0)
{
if(aux2 == aux3)
aux2 = aux2->right;
FibHeapLink(aux3,A[deg]);
aux3 = A[deg];
}
else
{
if(aux2 == A[deg])
aux2 = aux2->right;
FibHeapLink(A[deg],aux3);
}
A[deg] = NULL;
deg++;
}
A[deg] = aux3;
A[deg]->father = NULL;
aux = aux2;
}while(aux != A[aux->degree]);
(*H) = NULL;
for(int i=0;i<=2*dn;i++)
{
if(A[i]!=NULL)
insertFibHeap(H,A[i]);
}
};
int extractMin(FibHeap** H)
{
int index = (*H)->index;
if((*H)!=NULL)
{
nrNodes--;
FibHeap* aux = (*H)->child;
if(aux!=NULL)
{
do
{
FibHeap* aux2 = aux->right;
//add aux to the list of H
if(aux->father)
{
if(aux->father->degree == 1)
aux->father->child = NULL;
else
aux->father->child = aux->right;
aux->father->degree--;
aux->father = NULL;
}
if(aux!=aux->right)
{
aux->right->left = aux->left;
aux->left->right = aux->right;
}
else
aux2 = NULL;
aux->right = (*H);
aux->left = (*H)->left;
(*H)->left->right = aux;
(*H)->left = aux;
aux = aux2;
}while(aux != NULL);
}
//remove min from the root list of H
if((*H)!=(*H)->right)
{
(*H)->left->right = (*H)->right;
(*H)->right->left = (*H)->left;
FibHeap* aa = (*H)->right;
(*H)->left = NULL;
(*H)->right = NULL;
(*H) = aa;
consolidate(H);
}
else
(*H) = NULL;
}
return index;
};
void cutFibHeap(FibHeap* H, FibHeap* x, FibHeap* y)
{
//remove x from the child list of y, decrementig y->degree
if(y->child == NULL)
return;
if(y->degree == 1)
{
if(y->child == x)
y->child = NULL;
}
else
{
if(y->child == x)
y->child = x->right;
x->right->left = x->left;
x->left->right = x->right;
}
y->degree--;
x->father = NULL;
x->left = x;
x->right = x;
//add x to the root list of H
x->left = H->left;
x->right = H;
H->left->right = x;
H->left = x;
x->mark = false;
};
void cascadingCutFibHeap(FibHeap* H, FibHeap* y)
{
FibHeap* z = y->father;
if(z != NULL)
{
if(y->mark == false)
y->mark = true;
else
{
cutFibHeap(H,y,z);
cascadingCutFibHeap(H,z);
}
}
};
void decreaseKeyFibHeap(FibHeap** H, FibHeap* x, int new_index)
{
assert(compareIndex(new_index,x->index)<=0);
x->index = new_index;
FibHeap* y = x->father;
if(y!=NULL && compareIndex(x->index,y->index)<0)
{
cutFibHeap(*H,x,y);
cascadingCutFibHeap(*H,y);
}
if(compareIndex(x->index,(*H)->index)<0)
(*H) = x;
};
//------------------------------------------------------------------------------
//-------------------------------GRAF----------------------------------------
void adaug(int x,int y,int et)
{
graf* aux = new graf();
aux->et = et;
aux->nod = y;
aux->next = a[x];
a[x] = aux;
}
//------------------------------------------------------------------------------
void read()
{
ifstream f("dijkstra.in");
f>>N>>M;
int x,y,z;
for(int i=0;i<M;i++)
{
f>>x>>y>>z;
adaug(x-1,y-1,z);
}
f.close();
T[0] = true;
dist[0] = 0;
for(int i=1;i<N;i++)
{
T[i] = false;
dist[i] = INF;
}
graf* aux = new graf();
aux = a[0];
while(aux)
{
dist[aux->nod] = aux->et;
aux = aux->next;
}
Min = NULL;
nrNodes = 0;
for(int i=1;i<N;i++)
{
FibHeap *aux2 = createFibHeap(i);
nrNodes++;
insertFibHeap(&Min,aux2);
ARB[i-1] = aux2;
}
}
void solve()
{
int xp=INF;
while(Min && nrNodes>1)
{
xp = extractMin(&Min);
T[xp] = true;
graf* aux = new graf();
aux = a[xp];
while(aux)
{
if(!T[aux->nod] && dist[aux->nod]>(dist[xp]+aux->et))
{
dist[aux->nod] = dist[xp]+aux->et;
decreaseKeyFibHeap(&Min,ARB[aux->nod-1],aux->nod);
}
aux = aux->next;
}
}
ofstream g("dijkstra.out");
for(int i=1;i<N;i++)
if(dist[i]!=INF)
g<<dist[i]<<" ";
else
g<<"0 ";
g.close();
}
int main()
{
read();
solve();
return 0;
}