Cod sursa(job #115440)

Utilizator Binary_FireFlorin Pogocsan Binary_Fire Data 16 decembrie 2007 12:41:25
Problema Gather Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda 2, Clasele 11-12 Marime 1.53 kb
#include <cstdio>

#define fin  "gather.in"
#define fout "gather.out"

const int MAX = 2000000000;

int N,M,K;
int dp[100][1<<15];
int ind[100],nrb[1<<15];
int x[1000],y[1000],c[1000],d[1000];
int ret=MAX;

int min(int a,int b)
{
	if ( a < b )
		return a;
	else
		return b;
}

void readdata()
{
	int i,val;

	freopen(fin,"r",stdin);

	scanf("%d%d%d",&K,&N,&M);	

	for (i=0;i<K;++i)
	{
		scanf("%d",&val);
		ind[val]=i+1;
	}

	for (i=1;i<=M;++i)
		scanf("%d%d%d%d",&x[i],&y[i],&c[i],&d[i]);
}

void solve()
{
	int i,j,k;

	for ( i = 1 ; i <= N ; ++i )
	for ( j = 0 ; j < (1<<K); ++j)
		dp[i][j]=MAX;

	dp[1][0] = 0;

	for ( k = 0 ; k < ( 1<< K ) ; ++k )
	{
		for ( j = 0 ; (1<<j) <= k ; ++j )
			if ( k & ( 1 << j ) )
				nrb[k]++;
	}

	for ( i = 1 ; i <= N ; ++i )
		for ( j = 1 ; j <= M; ++j )
			for ( k = 0 ; k < ( 1 << K ) ; ++k )
			{
				if ( nrb[ k ] <= d[ j ] )
				{
					dp[ y[j] ][k] = min(dp[ x[j] ][k] + c[j],dp[ y[j] ][k]);
					dp[ x[j] ][k] = min(dp[ y[j] ][k] + c[j],dp[ x[j] ][k]);					
				
					if ( ind[ x[j] ] && !( ( 1 << ( ind[ x[j] ] - 1 ) ) & k ) )
						dp[ x[j] ][k | ( 1 << ( ind[ x[j] ] - 1 ) ) ] = min(dp[ x[j] ][k |  ( 1 << ( ind[ x[j] ] - 1 ) )],dp[y[j]][k]+c[j]); 
					if ( ind[ y[j] ] && !( ( 1 << ( ind[ y[j] ] - 1 ) ) & k ) )
						dp[ y[j] ][k | ( 1 << ( ind[ y[j] ] - 1 ) ) ] = min(dp[ y[j] ][k |  ( 1 << ( ind[ x[j] ] - 1 ) )],dp[x[j]][k]+c[j]); 
				}
			}

	for ( i = 1 ;i <= N; ++i )
		ret = min( ret , dp[i][1<<(K-1)] );
	
	freopen(fout,"w",stdout);

	printf("%d\n",ret);
}

int main()
{
	readdata();
	solve();

	return 0;
}