Cod sursa(job #489226)

Utilizator indestructiblecont de teste indestructible Data 1 octombrie 2010 20:39:37
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 kb
#include <stdio.h>
#include <vector>
#include <queue>
#define NMAX 755
#define KMAX 17
#define LMAX 1255
#define HMAX 1<<15
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define ll long long
#define INF 1LL<<55
using namespace std;
int k,n,m,A[KMAX];
struct info
{
	int a,b;
};
info B[LMAX];
vector < pair <int,int> > C[NMAX];
queue <int> Q;
ll best[NMAX],D[KMAX][KMAX][KMAX],E[HMAX][KMAX],rez;
char in[NMAX];
void read()
{
	scanf("%d%d%d",&k,&n,&m);
	int i,a,b,c,d;
	for (i=1; i<=k; i++)
		scanf("%d",&A[i]);
	A[0]=1;
	for (i=1; i<=m; i++)
	{
		scanf("%d%d%d%d",&a,&b,&c,&d);
		B[i].a=c; B[i].b=d;
		C[a].pb(mp(b,i));
		C[b].pb(mp(a,i));
	}
}
void init()
{
	int i;
	for (i=1; i<=n; i++)
		best[i]=INF;
}
void proceseaza(int st,int val)
{
	init();
	best[st]=0;
	Q.push(st);
	in[st]=1;
	int i,x,y,z,a,b;
	while (!Q.empty())
	{
		x=Q.front();
		Q.pop();
		in[x]=0;
		for (i=0; i<C[x].size(); i++)
		{
			y=C[x][i].f; z=C[x][i].s;
			a=B[z].a; b=B[z].b;
			if (b>=val && best[y]>best[x]+a)
			{
				best[y]=best[x]+a;
				if (!in[y])
					Q.push(y),in[y]=1;
			}
		}
	}
}
void precompute()
{
	int i,j,t;
	for (i=0; i<=k; i++)
		for (j=0; j<=k; j++)
		{
			proceseaza(A[i],j);
			for (t=1; t<=k; t++)
				D[i][j][t]=best[A[t]];
		}
}
void prep()
{
	int i,j;
	for (i=0; i<(1<<k); i++)
		for (j=0; j<=k; j++)
			E[i][j]=INF;
}
inline int nrb(int x)
{
	int i,s=0;
	for (i=1; i<=k; i++)
		if (x & 1<<(i-1))
			s++;
	return s;
}
inline ll min(ll x,ll y)
{
	return x<y ? x : y;
}
void solve()
{
	int i,j,t,x,y;
	prep();
	E[0][0]=0;
	for (i=1; i<(1<<k); i++)
	{
		x=nrb(i);
		for (j=1; j<=k; j++)
			if (i & 1<<(j-1))
			{
				y=i ^ (1<<(j-1));
				for (t=0; t<=k; t++)
					E[i][j]=min(E[i][j],E[y][t]+D[t][x-1][j]*x);
			}
	}
	rez=INF;
	for (i=1; i<=k; i++)
		rez=min(rez,E[(1<<k)-1][i]);
}
int main()
{
	freopen("gather.in","r",stdin);
	freopen("gather.out","w",stdout);
	read();
	precompute();
	solve();
	printf("%lld\n",rez);
	return 0;
}