Cod sursa(job #467780)

Utilizator ionutz32Ilie Ionut ionutz32 Data 30 iunie 2010 15:40:26
Problema Algoritmul Bellman-Ford Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <stdio.h>

struct nod
{
	int nr,c;
	nod *adr;
} *graf[50005],*u;
int n,m,i,x,y,z,s[50005],q[50005],st,dr,d[50005],heap[50005],root,poz[50005],aux,min;
bool k;

inline void heap_up(int p)
{
	while (p>1 && d[heap[p]]<d[heap[p/2]])
	{
		aux=heap[p];
		heap[p]=heap[p/2];
		heap[p/2]=aux;
		poz[heap[p]]=p;
		poz[heap[p/2]]=p/2;
		p/=2;
	}
}

inline void heap_down(int p)
{
	while ((p*2<=x && d[heap[p]]>d[heap[p*2]]) || (p*2+1<=x && d[heap[p]]>d[heap[p*2+1]]))
	{
		if (p*2+1<=x)
			if (d[heap[p*2]]<d[heap[p*2+1]])
				min=p*2;
			else
				min=p*2+1;
		else
			min=p*2;
		aux=heap[p];
		heap[p]=heap[min];
		heap[min]=aux;
		poz[heap[p]]=p;
		poz[heap[min]]=min;
		p=min;
	}
}	

int main()
{
	freopen("bellmanford.in","r",stdin);
	freopen("bellmanford.out","w",stdout);
	scanf("%d %d",&n,&m);
	for (i=1;i<=m;++i)
	{
		scanf("%d %d %d",&x,&y,&z);
		u=new nod;
		u->nr=y;
		u->c=z;
		u->adr=graf[x];
		graf[x]=u;
	}
	k=true;
	for (i=1;i<=n;++i)
		if (!s[i])
		{
			s[i]=i;
			q[1]=i;
			for (st=dr=1;st<=dr && k;++st)
				for (u=graf[q[st]];u && k;u=u->adr)
					if (u->c<0)
						if (s[u->nr]==i)
						{
							k=false;
							break;
						}
						else
						{
							s[u->nr]=i;
							q[++dr]=u->nr;
						}
		}
	if (!k)
	{
		printf("Ciclu negativ!");
		return 0;
	}
	for (i=2;i<=n;++i)
		d[i]=250000000;
	x=1;
	heap[1]=1;
	poz[1]=1;
	while (x)
	{
		root=heap[1];
		poz[root]=0;
		--x;
		if (x)
		{
			heap[1]=heap[x+1];
			poz[heap[1]]=1;
			heap_down(1);
		}
		for (u=graf[root];u;u=u->adr)
			if (d[root]+u->c<d[u->nr])
			{
				d[u->nr]=d[root]+u->c;
				if (poz[u->nr])
					heap_up(poz[u->nr]);
				else
				{
					heap[++x]=u->nr;
					heap_up(x);
				}
			}
	}
	for (i=2;i<=n;++i)
		printf("%d ",d[i]);
	return 0;
}