Cod sursa(job #390879)

Utilizator ada_sAda-Mihaela Solcan ada_s Data 4 februarie 2010 18:53:13
Problema Drumuri minime Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

const long NMAX=50010;
const long MMAX=250010;
const long INF=100000000;
const double EPS=0.0000000001;

long q[NMAX], *a[NMAX], n, x[MMAX], y[MMAX], m, d[NMAX], cont[NMAX], nr[NMAX];
int z[MMAX];
bool viz[NMAX], rez;
double *c[NMAX], dist[NMAX];

bool bellmanford(long nod);

int main()
{
	long i;
	freopen("dmin.in", "r", stdin);
	freopen("dmin.out", "w", stdout);
	scanf("%ld%ld", &n, &m);
	for (i=1; i<=m; i++)
	{
		scanf("%ld%ld%d", &x[i], &y[i], &z[i]);
		d[x[i]]++;
	}//for i
	for (i=1; i<=n; i++)
	{
		a[i]=new long[d[i]+1];
		c[i]=new double[d[i]+1];
		a[i][0]=0;
		c[i][0]=0;
	}//for i
	for (i=1; i<=m; i++)
	{
		a[x[i]][++a[x[i]][0]]=y[i];
		c[x[i]][a[x[i]][0]]=log(z[i]);
	}//for i
	rez=bellmanford(1);
	if (rez)
		printf("Ciclu negativ!");
	else
		for (i=2; i<=n; i++)
			printf("%ld ", nr[i]);
	return 0;
}//main

bool bellmanford(long nod)
{
	long p=0, u=0, i;
	bool cicluNeg=0;
	for (i=1; i<=n; i++)
		dist[i]=INF;
	q[u]=nod;
	if (u<NMAX)
		u++;
	else
		u=0;
	nr[nod]=1;
	viz[nod]=1;
	dist[nod]=0;
	cicluNeg=0;
	while ((p!=u)&&(!cicluNeg))
	{
		nod=q[p];
		if (p<NMAX)
			p++;
		else
			p=0;
		if (viz[nod])
		{
			for (i=1; i<=a[nod][0]; i++)
				if (abs(dist[a[nod][i]]-(dist[nod]+c[nod][i]))<=EPS)
					nr[a[nod][i]]+=nr[nod];
				else
					if (dist[a[nod][i]]>(dist[nod]+c[nod][i]))
					{
						if (!viz[a[nod][i]])
						{
							if (cont[a[nod][i]]>n)
								cicluNeg=1;
  						else
							{
								q[u]=a[nod][i];
								if (u<NMAX)
									u++;
								else
									u=0;
								viz[a[nod][i]]=1;
								cont[a[nod][i]]++;
							}//else
						}//if
						dist[a[nod][i]]=dist[nod]+c[nod][i];
						nr[a[nod][i]]=nr[nod];
					}//if
			viz[nod]=0;
		}//if
	}//while
	if (cicluNeg)
		return 1;
	else
		return 0;
}//bellmanford