Cod sursa(job #471005)

Utilizator RaphyRafailescu Marius Raphy Data 16 iulie 2010 15:13:00
Problema Algoritmul lui Dijkstra Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.51 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <set>
using namespace std;

#define infinit 0x3f3f3f3f

typedef struct elem{
	int key,loc;
	void *val;
} *Elem;

typedef struct heap{
	int n,max;
	Elem *a;
} *PQ;

PQ PQ_New(){
	PQ h = (PQ) malloc (sizeof (struct heap));
	h->n = 0;
	h->max=100;
	h->a=(Elem*) malloc(100*sizeof(Elem));
	return h;
}

int PQ_Size(PQ h){
	return h->n;
}
int PQ_Empty(PQ h){
	return h->n == 0;
}
int PQ_Full(PQ h){
	return h->n == h->max;
}
Elem PQ_Min(PQ h){
	return h->a[0];
}

int FiltruJos(PQ h,int p,int n){
	int fiu,locf,locp;
	Elem t=h->a[p];
	for (;2*p+1<n;p=fiu){
		fiu = 2*p+1;
		if (fiu+1<n && h->a[fiu]->key>h->a[fiu+1]->key) fiu++;
		if (t->key<=h->a[fiu]->key) break;
		locf=h->a[fiu]->loc;
		locp=h->a[p]->loc;
		Elem aux = h->a[p];
		h->a[p]=h->a[fiu];
		h->a[p]->loc=locp;
		h->a[fiu]=aux;
		h->a[fiu]->loc=locf;
	}
	t->loc = p;
	return t->loc;
}
int FiltruSus(PQ h,int p){
	int tata=p,locp,loct;
	Elem t=h->a[p];
	while(p>0){
		tata=(p-1)/2;
		if (t->key >= h->a[tata]->key) break;
		loct=h->a[tata]->loc;
		locp=h->a[p]->loc;
		Elem aux = h->a[p];
		h->a[p]=h->a[tata];
		h->a[tata]=aux;
		h->a[tata]->loc=loct;
		h->a[p]->loc=locp;
		p=tata;
	}
	t->loc=p;
	return t->loc;
}

int PQ_Insert(PQ h, int k, void *v){
	Elem e;
	e=(Elem) malloc (sizeof (struct elem));
	e->key = k;
	e->val=v;
	e->loc = h->n;
	h->a[h->n] = e;
	h->n++;
	return FiltruSus(h,h->n-1);
}

Elem PQ_DelMin(PQ h){
	Elem t = h->a[0];
	h->a[0]=h->a[h->n-1];
	h->a[0]->loc=0;
	h->n--;
	FiltruJos(h,0,h->n);
	return t;
}

int PQ_ChPr(PQ h,int k,int p){
	int kv = h->a[p]->key;
	h->a[p]->key = k;
	if (kv < k)
		return FiltruJos(h,p,h->n);
	return FiltruSus(h,p);
}

void CrHeap(PQ h){
	int i;
	for (i=(h->n-2)/2;i>=0;i--)
		FiltruJos(h,i,h->n);
}

int *alocint(int x){
	int *p = (int *)malloc(sizeof(int));
	*p=x;
	return p;
}

typedef struct{
	int dist,parinte;
	vector<int> vecini;
}nod,*pnod;

typedef pnod *Graf;

int n,m,**cost,sursa=0;
Graf graf;
PQ h = PQ_New();

void Estimare(){
	for (int i = 0; i < n; i++){
		graf[i]->dist = infinit;
		graf[i]->parinte = -1;
		PQ_Insert(h,infinit,alocint(i));
	}
	graf[sursa]->dist = 0;
	PQ_ChPr(h,0,sursa);
}

void dijkstra(){
	Estimare();
	Elem e;
	int nod,vecin;
	vector<int>::iterator it;
	set<int> S;
	while(!PQ_Empty(h)){
		e = PQ_DelMin(h);
		nod = *(int*)e->val;
		S.insert(nod);
		for (it = graf[nod]->vecini.begin(); it != graf[nod]->vecini.end(); it++){
			vecin = *it;
			if (S.find(vecin) == S.end() && graf[vecin]->dist > graf[nod]->dist + cost[nod][vecin]){
				graf[vecin]->dist = graf[nod]->dist + cost[nod][vecin];
				graf[vecin]->parinte = nod;
				PQ_ChPr(h,graf[vecin]->dist,vecin);
			}
		}
	}
}

int main(){
	FILE *in,*out;
	in = fopen("dijkstra.in","r");
	out = fopen("dijkstra.out","w");
	fscanf(in,"%d%d",&n,&m);
	int s,d,c;
	
	graf = new pnod[n];

	cost = (int**)malloc(n*sizeof(int*));
	
	for (int i = 0; i < n; ++i){
		cost[i]=(int*)malloc(n*sizeof(int));
		graf[i] = new nod;
	}
	for (int i = 0; i < m; ++i){
		fscanf(in, "%d%d%d", &s,&d,&c);
		
		cost[s-1][d-1] = c;
		
		graf[s-1]->vecini.push_back(d-1);
		
	}
	dijkstra();
	for (int i = 1; i < n; ++i)
		if (graf[i]->dist != infinit)
			fprintf(out,"%d ",graf[i]->dist);
		else
			fprintf(out,"0 ");
	for (int i = 0; i < n; ++i){
		free(cost[i]);
		delete graf[i];
	}
	free(cost);
	delete graf;
	fclose(in);
	fclose(out);
	return 0;
}