Cod sursa(job #115546)

Utilizator MarcvsHdrMihai Leonte MarcvsHdr Data 16 decembrie 2007 12:57:07
Problema Gather Scor 20
Compilator cpp Status done
Runda preONI 2008, Runda 2, Clasele 11-12 Marime 3.18 kb
# include <stdio.h>
# include <stdlib.h>

const long int MAXN=750;
const long int INF=2000000000;

typedef struct NODL{long int nod,cost,cap;NODL *next;};
typedef struct LIST{NODL *prim,*ultim;};

LIST ladiac[MAXN+1];
long int used[MAXN+1],uused[30],vv[20],k,n,m,camera[30],solbest,r[MAXN+1],index[MAXN+1],heap[MAXN+1],heaplen;

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

void citire()
{
long int i,aa,bb,cost,cap;
FILE *f=fopen("gather.in","r");
fscanf(f,"%ld%ld%ld",&k,&n,&m);
for (i=1;i<=k;i++)
	fscanf(f,"%ld",&camera[i]);
for (i=1;i<=m;i++)
	{
	fscanf(f,"%ld%ld%ld%ld",&aa,&bb,&cost,&cap);
	add(aa,bb,cost,cap);
	add(bb,aa,cost,cap);
	}
fclose(f);
}

///////////////////
// HEAP HANDLERS
//////////////////

void rise_heap(long int i)
{
long int aux;
while (i/2&&r[heap[i]]<r[heap[i/2]])
	{
	aux=heap[i];heap[i]=heap[i/2];heap[i/2]=aux;
	index[heap[i]]=i;
	index[heap[i/2]]=i/2;
	i/=2;
	}
}

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

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

void insert_heap(long int nod) {heap[++heaplen]=nod;rise_heap(heaplen);}

long int dijkstra(long int source, long int dest, long int stage)
{
long int i,node;
for (i=1;i<=n;i++)
	r[i]=INF;
used[source]=1;
r[source]=0;
NODL *p=ladiac[source].prim;
while (p)
	{
	if ((*p).cap<=stage) r[(*p).nod]=(*p).cost*stage;
	p=(*p).next;
	}
for (i=1;i<=n;i++) if (i!=source) insert_heap(i);
while (index[dest])
	{
	node=extract_heap();
	p=ladiac[node].prim;
	while (p)
		{
		if (!used[(*p).nod]&&(*p).cap<=stage&&(r[(*p).nod]==-1||(r[(*p).nod]>r[node]+(*p).cost*stage)))
			{
			r[(*p).nod]=r[node]+(*p).cost*stage;
			rise_heap(index[(*p).nod]);
			}
		p=(*p).next;
		}
	}
return r[dest];
}

void eval()
{
long int stage,solloc=0;
vv[0]=0;
camera[vv[0]]=1;
long int i;
for (i=1;i<=k;i++) used[camera[vv[i]]]=1;
//vom face dijkstra-uri pe rand
for (stage=1;stage<=k;stage++)
	{
	solloc+=dijkstra(camera[vv[stage-1]],camera[vv[stage]],stage);
	used[camera[vv[stage-1]]]=0;
	solloc++;
	solloc--;
	}
if (solbest==0||solloc<solbest) solbest=solloc;
}

void gen(long int kk)
{
long int i,j;
for (i=1;i<=k;i++)
	if (!uused[i])
		{
		vv[kk]=i;
		uused[i]=1;
		if (kk==k)
			{
			//for (j=1;j<=k;j++)
			//	printf("%d ",vv[j]);
			//printf("\n");
			eval();
			}
		else gen(kk+1);
		uused[i]=0;
		}
}

void scrie()
{
FILE *g=fopen("gather.out","w");
fprintf(g,"%ld\n",solbest);
fcloseall();
}

int main()
{
citire();
gen(1);
scrie();
return 0;
}