Cod sursa(job #398575)

Utilizator AndreyPAndrei Poenaru AndreyP Data 18 februarie 2010 23:10:07
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.69 kb
#include<stdio.h>
#include<stdlib.h>
#define N 503
#define P 53
struct ajt
{
	short x,y,z;
};
short p,n;
struct pss
{
	short x,y;
};
const long inf=1000000000;
pss a[N][N];
short deg[N];
short marcat[N];
short q[N];
char inq[N];
long d[P][N];
short dest[P];
short dd=0;
long b[P][P][2];
void dijkstra(short now)
{
	short i;
	short next;
	for(i=1; i<=n; ++i)
	{
		inq[i]=0;
		d[dd][i]=inf;
	}
	q[0]=1;
	q[1]=now;
	d[dd][now]=0;
	inq[now]=1;
	long cost;
	short poz;
	while(q[0]>0)
	{
		poz=1;
		for(i=2; i<=q[0]; ++i)
		{
			if(d[dd][q[poz]]>d[dd][q[i]])
				poz=i;
		}
		now=q[poz];
		inq[now]=0;
		if(q[0]>1)
		{
			q[poz]=q[q[0]];
			--q[0];
		}
		else
			--q[0];
		for(i=0; i<deg[now]; ++i)
		{
			next=a[now][i].x;
			cost=d[dd][now]+(long)a[now][i].y;

			if(d[dd][next]>cost)
			{
				d[dd][next]=cost;
				if(inq[next]==0)
				{
					inq[next]=1;
					q[++q[0]]=next;
				}
			}
		}
	}
}
void citire()
{
	long m;
	scanf("%hd%hd%ld",&p,&n,&m);
	short x,y,z;
	long i;
	for(i=0; i<m; ++i)
	{
		scanf("%hd%hd%hd",&x,&y,&z);
		a[x][deg[x]].x=y;
		a[x][deg[x]].y=z;
		++deg[x];

		a[y][deg[y]].x=x;
		a[y][deg[y]].y=z;
		++deg[y];
	}
	short j;
	dd=1;
	marcat[1]=1;
	dijkstra(1);
	for(j=1; j<=p; ++j)
	{
		scanf("%hd",&dest[j]);
		if(marcat[dest[j]]!=0)
			continue;
		++dd;
		marcat[dest[j]]=dd;
		dijkstra(dest[j]);
	}
}
inline long minim(long x,long y)
{
	if(x<y)
		return x;
	return y;
}
void rezolva()
{
	b[1][1][0]=inf;
	b[p][p][1]=inf;
	b[1][1][1]=d[marcat[dest[1]]][dest[2]];
	b[p][p][0]=d[marcat[dest[p-1]]][dest[p]];
	short i,j,k,t;

	for(i=2; i<p; ++i)
	{
		b[i][i][0]=d[marcat[dest[i]]][dest[i-1]];
		b[i][i][1]=d[marcat[dest[i]]][dest[i+1]];
	}

	for(k=1; k<p; ++k)
	{
		for(i=1; i+k<=p; ++i)
		{
			j=i+k;
			if(i!=1)
			{
				b[i][j][0]=b[i+1][j][0]+d[marcat[dest[i]]][dest[i-1]];
				b[i][j][0]=minim(b[i][j][0],b[i][j-1][1]+d[marcat[dest[i-1]]][dest[j]]);
				b[i][j][0]=minim(b[i][j][0],inf);
				for(t=i+1; t<j; ++t)
					b[i][j][0]=minim(b[i][j][0],b[i][t-1][1]+b[t+1][j][0]+d[marcat[dest[i-1]]][dest[t]]);
			}
			else
				b[i][j][0]=inf;

			if(j!=p)
			{
				b[i][j][1]=b[i+1][j][0]+d[marcat[dest[i]]][dest[j+1]];
				b[i][j][1]=minim(b[i][j][1],b[i][j-1][1]+d[marcat[dest[j+1]]][dest[j]]);
				b[i][j][1]=minim(b[i][j][1],inf);
				for(t=i+1; t<j; ++t)
					b[i][j][1]=minim(b[i][j][1],b[i][t-1][1]+b[t+1][j][0]+d[marcat[dest[j+1]]][dest[t]]);
			}
			else
				b[i][j][1]=inf;
		}
	}
	long rez=minim(b[2][p][0]+d[1][dest[1]],b[1][p-1][1]+d[1][dest[p]]);

	for(t=2; t<p; ++t)
		rez=minim(rez,b[1][t-1][1]+b[t+1][p][0]+d[1][dest[t]]);

	printf("%ld\n",rez);
}
int main()
{
	freopen("team.in","r",stdin);
	freopen("team.out","w",stdout);

	citire();
	if(p==1)
	{
		printf("%ld\n",d[1][dest[1]]);
		return 0;
	}
	rezolva();

	return 0;
}