Cod sursa(job #494089)

Utilizator SheepBOYFelix Liviu SheepBOY Data 20 octombrie 2010 18:40:43
Problema Algoritmul lui Dijkstra Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.43 kb
#include<stdio.h>
#include<stdlib.h>

#define MAXNOD 50100
#define MAXMUC 250100
#define INF 300000000
struct heap{
int cost,nd;
};
struct PNT{
int x,y,c;
};
int n,m,nh,start;
heap hp[MAXNOD<<1];
int pre[MAXNOD],where[MAXNOD],cost[MAXNOD];
PNT graf[MAXMUC];

void scan()
{
	scanf("%d%d",&n,&m);
	int i;
	int aux1,aux2,aux3;
	for(i=0;i<m;++i)
	{
		scanf("%d%d%d",&aux1,&aux2,&aux3);
		graf[i].x=aux1;
		graf[i].y=aux2;
		graf[i].c=aux3;
	}
}
void DNormalise(int pos)
{
	if(hp[(pos<<1)].cost==0||hp[(pos<<1)+1].cost==0)
		return ;
	
		if(hp[pos].cost>hp[(pos<<1)].cost && hp[(pos<<1)].cost< hp[(pos<<1)+1].cost)
		{
			int aux;
			aux=hp[pos].cost;
			hp[pos].cost=hp[(pos<<1)].cost;
			hp[(pos<<1)].cost=aux;
		
			aux=hp[pos].nd;
			hp[pos].nd=hp[(pos<<1)].nd;
			hp[(pos<<1)].nd=aux;
		
			aux=where[hp[pos].nd];
			where[hp[pos].nd]=where[hp[(pos<<1)].nd];
			where[hp[(pos<<1)].nd]=aux;
		
			DNormalise((pos<<1));
		}
		
		if(hp[pos].cost>hp[(pos<<1)+1].cost)
		{
			int aux;
			aux=hp[pos].cost;
			hp[pos].cost=hp[(pos<<1)+1].cost;
			hp[(pos<<1)+1].cost=aux;
		
			aux=hp[pos].nd;
			hp[pos].nd=hp[(pos<<1)+1].nd;
			hp[(pos<<1)+1].nd=aux;
		
			aux=where[hp[pos].nd];
			where[hp[pos].nd]=where[hp[(pos<<1)+1].nd];
			where[hp[(pos<<1)+1].nd]=aux;
		
			DNormalise((pos<<1)+1);
		}
}
void Normalise(int pos)
{
	if(pos>1)
		if(hp[pos].cost<hp[pos/2].cost)
		{
			int aux;
			aux=hp[pos].cost;
			hp[pos].cost=hp[pos/2].cost;
			hp[pos/2].cost=aux;
		
			aux=hp[pos].nd;
			hp[pos].nd=hp[pos/2].nd;
			hp[pos/2].nd=aux;
		
			aux=where[hp[pos].nd];
			where[hp[pos].nd]=where[hp[pos/2].nd];
			where[hp[pos/2].nd]=aux;
		
			Normalise(pos>>1);
		}
		
}

void InsertHeap(int pos,int val)
{
	hp[nh+1].cost=val;
	hp[nh+1].nd=pos;
	Normalise(nh+1);
	++nh;
}
int FindNod(int val)
{
	int st=0,dr=m-1,mij;
	while(st<dr)
	{
		mij=((st+dr)>>1);
		if(graf[val].x<=graf[mij].x)
			dr=mij;
		if(graf[val].x>graf[mij].x)
			st=mij+1;
		
	}
	return st;
}
inline void CutOff(int pos)
{
	hp[pos].cost=INF+1;
	DNormalise(pos);
}
void dij()
{
	//init
	int i;
	for(i=1;i<=n;++i)
	{
		where[i]=nh+1;
		if(i!=start)
		{
			InsertHeap(i,INF);
			pre[i]=start;
			cost[i]=INF;
		}
		else
		{
			InsertHeap(i,0);
			pre[i]=0;
			cost[i]=0;
		}
	}
	
	//calculate
	int nov=0,cp;
	i=0;
	
	while(nov<=n)
	{
		i=FindNod(hp[1].nd);
		//for each neighhbor
		cp=graf[i].x;
		while(graf[i].x==cp)
		{
			//if we've found a better path
			if(hp[where[graf[i].x]].cost+graf[i].c<hp[where[graf[i].y]].cost)
			//if(cost[graf[i].x]+graf[i].c<cost[graf[i].y])	
			{
				//we update the cost
				pre[graf[i].y]=graf[i].x;
				hp[where[graf[i].y]].cost=hp[where[graf[i].x]].cost+graf[i].c;
				cost[graf[i].y]=cost[graf[i].x]+graf[i].c;
				//and normalise the heap
				Normalise(where[graf[i].y]);
			}
			++i;
		}
		
		CutOff(where[cp]);
		++nov;
	}
	
	//print
	for(i=2;i<=n;++i)
		if(cost[i]<INF)
			printf("%d ",cost[i]);
		else
			printf("0 ");
}
int cmp(const void *a,const void *b)
{
	PNT x,y;
	x=*(PNT *)a;
	y=*(PNT *)b;
	
	if(x.x<y.x)
		return -1;
	if(x.x>y.x)
		return 1;
	if(x.x==y.x)
	{
		if(x.y<y.y)
			return -1;
		if(x.y>y.y)
			return 1;
		
		return 0;
	}
}
int main()
{
	freopen("dijkstra.in","r",stdin);
	freopen("dijkstra.out","w",stdout);
	start=1;
	
	scan();
	qsort(graf,m,sizeof(graf[0]),cmp);
	dij();
	
	return 0;
}