Cod sursa(job #586345)

Utilizator VladberilaVladutz Vladberila Data 30 aprilie 2011 16:21:44
Problema Algoritmul lui Dijkstra Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.79 kb
#define inf 1001
#include <cstdio>
#include <fstream>
#include <malloc.h>
using namespace std;
ifstream f("dijkstra.in");
ofstream g("dijkstra.out");

unsigned long n,m,**A,*d,*pre,*Q,*pos,aux,*sel;
int **C;

void citire()
{
	unsigned long x,y,i;
	f>>n>>m;
	aux=n;
	sel=(unsigned long*)malloc((n+1)*sizeof(unsigned long));
	pos=(unsigned long*)malloc((n+1)*sizeof(unsigned long));
	Q=(unsigned long*)malloc((n+1)*sizeof(unsigned long));
	d=(unsigned long*)malloc((n+1)*sizeof(unsigned long));
	pre=(unsigned long*)malloc((n+1)*sizeof(unsigned long));
	C=(int**)malloc((n+1)*sizeof(int*));
	for(i=1;i<=n;i++)
		C[i]=(int*)malloc((n+1)*sizeof(int));
	A=(unsigned long**)malloc((n+1)*sizeof(unsigned long*));
	for(i=1;i<=n;i++)
	{
		A[i]=(unsigned long*)malloc(sizeof(unsigned long));
		A[i][0]=0;
	}
	for(i=1;i<=m;i++)
	{
		f>>x>>y;
		f>>C[x][y];
		A[x][0]++;
		A[x]=(unsigned long*)realloc(A[x],(A[x][0]+1)*sizeof(unsigned long));
		A[x][A[x][0]]=y;
	}
	f.close();
}

void init()
{
     unsigned long i;
     for(i=1;i<=n;i++)
     {
          pos[i]=i;
          Q[i]=i;
          d[i]=inf;
          pre[i]=1;
		  sel[i]=0;
     }
     pre[1]=0;
     d[1]=0;
     for(i=1;i<=A[1][0];i++)
        d[A[1][i]]=C[1][A[1][i]];
}

void combina(unsigned long i,unsigned long n)
{
    unsigned long tata=i,fiu=2*i,v=d[Q[i]],x=Q[i],p=pos[Q[fiu]];
    int ok=0;
    while(fiu<=n)
    {
        if(fiu<n)
            if(d[Q[fiu+1]]<d[Q[fiu]])
               ++fiu;
        if(v>d[Q[fiu]])
        {
            Q[tata]=Q[fiu];
			pos[Q[fiu]]=tata;
			tata=fiu;
			fiu*=2;
			if(ok)
				p*=2;
			ok=1;
        }
        else
           fiu=n+1;
    }
    Q[tata]=x;
    if(ok)
       pos[Q[tata]]=p;
}

void creareMinHeap()
{
    unsigned long i;
    for(i=n/2;i>=1;i--)
        combina(i,n);
}

void update_heap(unsigned long x) //deoarece cheia unui nod nu se poate mari ci doar micsora este suficient sa actualizez heap-ul doar in sus
{
	unsigned long fiu=pos[x],tata=fiu/2,aux,p;
	while(tata && d[Q[fiu]]<d[Q[tata]])
	{
		p=tata;
		aux=Q[tata];
		pos[Q[tata]]=fiu;
		Q[tata]=Q[fiu];
		pos[Q[fiu]]=p;
		Q[fiu]=aux;
		fiu=tata;
		tata=fiu/2;
	}
}

unsigned long extrageMin()
{
	unsigned long minim=Q[1];
	Q[1]=Q[n];
	pos[Q[n]]=1;
	--n;
	combina(1,n);
	return minim;
}

int main()
{
	unsigned long i,x,j;
	citire();
	init();
	creareMinHeap();
	x=extrageMin();
	sel[x]=1;
	for(i=1;i<=aux-1;i++)
	{
		x=extrageMin();
		sel[x]=1;
		for(j=1;j<=A[x][0];j++)
			if(!sel[A[x][j]])
				if(d[A[x][j]]>d[x]+C[x][A[x][j]])
				{
					pre[A[x][j]]=x;
					d[A[x][j]]=d[x]+C[x][A[x][j]];
					update_heap(A[x][j]);
				}
	}
	for(i=2;i<=aux;i++)
		if(d[i]==inf)
			g<<0<<' ';
		else
			g<<d[i]<<' ';
    g.close();
	return 0;
}