Cod sursa(job #75857)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 6 august 2007 13:17:01
Problema Distante Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.46 kb
# include <stdio.h>
# include <stdlib.h>

const long int MAXN=50000; //AICI!!! 50000
const long int INFINIT=1000000000;

typedef struct NOD {long int inf,cost; NOD *next;};
typedef struct NODL {NOD *prim,*ultim;};
NODL ladiac[MAXN+1];
long int n,heap[MAXN+1],index[MAXN+1],r[MAXN+1],m,s,heaplen,target[MAXN+1];

////////////////////////////////
// LIST handlers
////////////////////////////////

void add(long int loc, long int inf, long int cost)
{
NOD *p;
p=(NOD*) malloc (sizeof(NOD));
(*p).next=NULL;
(*p).inf=inf;
(*p).cost=cost;
if (ladiac[loc].prim)
	{
	(*ladiac[loc].ultim).next=p;
	ladiac[loc].ultim=p;
	}
else
	{
	ladiac[loc].prim=p;
	ladiac[loc].ultim=p;
	}
}

void destroy_list()
{
NOD *p,*q;
long int i;
for (i=1;i<=n;i++)
	{
	p=ladiac[i].prim;
	while (p)
		{
		q=p;
		p=(*p).next;
		free(q);
		}
	ladiac[i].prim=NULL;
	ladiac[i].ultim=NULL;
	}
}

////////////////////////////////
// HEAP handlers
////////////////////////////////

void destroy_heap()
{
long int i;
for (i=1;i<=n;i++) index[i]=0;
for (i=1;i<=heaplen;i++) heap[i]=0;
heaplen=0;
}

void float_heap(long int i)
{
long int min=i/2,auxi;
while (min&&r[heap[i]]<r[heap[min]])
	{
	auxi=heap[i];heap[i]=heap[min];heap[min]=auxi;
	auxi=index[heap[i]];index[heap[i]]=index[heap[min]];index[heap[min]]=auxi;
	i=min;
	min=i/2;
	}
}

void submerge_heap(long int i)
{
long int min,auxi;
do
	{
	min=i;
	if (2*i<=heaplen&&r[heap[2*i]]<r[heap[min]]) min=2*i;
	if (2*i+1<=heaplen&&r[heap[2*i+1]]<r[heap[min]]) min=2*i+1;
	if (min==i) break;
	auxi=heap[i];heap[i]=heap[min];heap[min]=auxi;
	auxi=index[heap[i]];index[heap[i]]=index[heap[min]];index[heap[min]]=auxi;
	i=min;
	}
while (1);
}

long int extract_root_heap()
{
long int sol=heap[1];
index[heap[1]]=0;
heap[1]=heap[heaplen];
heap[heaplen]=0;
index[heap[1]]=1;
heaplen--;
submerge_heap(1);
return sol;
}

////////////////////////////////
// DIJKSTRA
////////////////////////////////

void init()
{
long int i;
for (i=1;i<=n;i++)
	{
	r[i]=INFINIT;
	index[i]=0;
	}
NOD *p;
p=ladiac[s].prim;
while (p)
	{
	r[(*p).inf]=(*p).cost;
	p=(*p).next;
	}
r[s]=0;
for (i=1;i<=n;i++)
	if (i!=s)
	{
	heaplen++;
	heap[heaplen]=i;
	index[i]=heaplen;
	float_heap(heaplen);
	}
}

void update(long int nod)
{
NOD *p;
p=ladiac[nod].prim;
while (p)
	{
	if (index[(*p).inf])
		if (r[nod]+(*p).cost<r[(*p).inf])
			{
			r[(*p).inf]=(*p).cost+r[nod];
			float_heap(index[(*p).inf]);
			}
	p=(*p).next;
	}
}


void dijkstra()
{
init();
long int nod;
while (heaplen)
	{
	nod=extract_root_heap();
	update(nod);
	}
}

////////////////////////////////
// MAIN and main calls
////////////////////////////////

void citire(FILE *f);
void scrie(FILE *g);

int main()
{
FILE *f=fopen("distante.in","r");
FILE *g=fopen("distante.out","w");
long int i,t;
fscanf(f,"%ld",&t);
for (i=1;i<=t;i++)
	{
	citire(f);
	dijkstra();
	scrie(g);
	destroy_list();
	destroy_heap();
	}
fcloseall();
return 0;
}

////////////////////////////////
// INPUT AND OUTPUT
////////////////////////////////

void citire(FILE *f)
{
fscanf(f,"%ld%ld%ld",&n,&m,&s);
long int i,aa,bb,cc;
for (i=1;i<=n;i++) fscanf(f,"%ld",&target[i]);
for (i=1;i<=m;i++)
	{
	fscanf(f,"%ld%ld%ld",&aa,&bb,&cc);
	add(aa,bb,cc);
	add(bb,aa,cc);
	}
}

void scrie(FILE *g)
{
long int i,ok=1;
for (i=1;i<=n&&ok;i++) if (r[i]!=target[i]) ok=0;
if (ok) fprintf(g,"DA\n");
else fprintf(g,"NU\n");
}