Cod sursa(job #694537)

Utilizator stay_awake77Cangea Catalina stay_awake77 Data 27 februarie 2012 21:38:26
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

#define NMAX 2001
#define SMAX (1<<15)
#define KMAX 16
#define INF 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define nod first
#define cost second

int N, M, K, i, j, x, y, c, Config, Oras[KMAX], CMin[KMAX][NMAX], D[SMAX][KMAX], Sol;
vector< pair< int, int > > G[NMAX];

struct comp
{
	bool operator() (const int &X, const int &Y)
	{
		return ( CMin[i][X] > CMin[i][Y] );
	}
};

inline void Dijkstra( int Sursa, int *Dist )
{
	memset( Dist, INF, NMAX<<2 );
	Dist[Sursa] = 0;
	
	priority_queue< int, vector< int >, comp > Q;
	Q.push( Sursa );
	
	while( !Q.empty() )
	{
		int Nod = Q.top();
		Q.pop();
		
		for( vector< pair< int, int > >::iterator it = G[Nod].begin(); it != G[Nod].end(); ++it )
			if( Dist[ (*it).nod ] > Dist[Nod] + (*it).cost )
			{
				Dist[ (*it).nod ] = Dist[Nod] + (*it).cost;
				Q.push( (*it).nod );
			}
	}
}

int main()
{
	freopen("ubuntzei.in", "r", stdin);
	freopen("ubuntzei.out", "w", stdout);
	
	scanf("%d%d%d", &N, &M, &K );
	for( i = 0; i < K; ++i )
		scanf("%d", &Oras[i] );
	for( ; M--; )
	{
		scanf("%d%d%d", &x, &y, &c );
		G[x].pb( mp( y, c ) );
		G[y].pb( mp( x, c ) );
	}
	
	Dijkstra( 1, CMin[K] );
	if( !K )
	{
		printf("%d\n", CMin[K][N] );
		return 0;
	}
	for( i = 0; i < K; ++i )
		Dijkstra( Oras[i], CMin[i] );
	
	D[0][1] = 0;
	for( Config = 1; Config < (1<<K); ++Config )
	{
		for( i = 0; i < K; ++i )
			if( Config == (1<<i) )
			{
				D[Config][i] = CMin[K][ Oras[i] ];
				break;
			}
		if( Config == (1<<i) ) continue;
		
		for( i = 0; i < K; ++i )
		{
			D[Config][i] = INF;
			if( !(Config&(1<<i)) ) continue;
			
			for( j = 0; j < K; ++j )
				if( i != j && (Config&(1<<j)) )
					D[Config][i] = min( D[Config][i], D[Config - (1<<i)][j] + CMin[j][ Oras[i] ] );
		}
	}
	
	Sol = INF;
	for( i = 0; i < K; ++i )
		Sol = min( Sol, D[(1<<K)-1][i] + CMin[i][N] );
	
	printf("%d\n", Sol );
	
	return 0;
}