Cod sursa(job #1027741)

Utilizator superman_01Avramescu Cristian superman_01 Data 12 noiembrie 2013 23:46:11
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

#define INF 0x3f3f3f3f
#define MAX_SIZE 2005
#define KMAX 20 
#define TYPE pair < int , int >
using namespace std;

ifstream in ( "ubuntzei.in" );
ofstream out ( "ubuntzei.out" );

typedef vector < pair < int , int > > ::iterator IT;
priority_queue < TYPE , vector < TYPE > , greater < TYPE > > Heap;
int N ,M , special[KMAX] , K, DP[(1<<KMAX)][KMAX];
int Cost[KMAX][KMAX] , Answer , Destination , Source , Dist[MAX_SIZE];
vector < pair < int , int > > G[MAX_SIZE] ;
vector < int > NewG[MAX_SIZE];

void Hamilton ( int n )
{
	int i , j  ;
	for ( i = 0 ; i < ( 1<<n) ; ++i )
		for( j = 0 ; j < n ; ++j )
			DP[i][j] = INF;
	DP[1][Source] = 0;
	
	for ( i = 0 ; i < ( 1 << n ) ; ++i )
		for ( j = 0 ; j < n ; ++j )
			if ( i && ( 1<<j) )
				for ( size_t k = 0 ; k < NewG[j].size() ; ++k )
					if ( i && (1<<NewG[j][k]) )
					DP[i][j] = min ( DP[i][j]  , DP[ i^ ( 1<<j)][NewG[j][k]] + Cost[NewG[j][k]][j]) ;
	Answer = DP[(1<<n) - 1 ][Destination];
			
}

void Dijkstra ( int start_node )
{
	int node ;
    memset ( Dist , INF , sizeof ( Dist) );
	Dist[start_node] = 0 ;
	Heap.push ( make_pair ( 0 ,start_node ) );
	while ( !Heap.empty() )
	{
		node = Heap.top().second;
		Heap.pop();
		for ( IT it = G[node].begin() ; it != G[node].end(); ++it )
		{
			if ( Dist[it->first] > Dist[node] + it->second )
			{
				Dist[it->first]  = Dist[node] + it->second;
				Heap.push( make_pair ( Dist[it->first] , it->first) );
			}
		}
	}
}

int main ( void )
{
	int i , j , x ,y , cost ;
	in >> N >> M  >>K  ;
	for ( i = 1 ; i <= K ; in >> special[i++] );
	for ( i = 1 ; i <= M ; ++i )
	{
		in >> x >> y >> cost;
		G[x].push_back( make_pair ( y , cost ) );
		G[y].push_back( make_pair ( x , cost ) );		
	}
	Dijkstra ( 1 ) ;
	Source = 0 ;
	Destination = K + 1 ;
	for ( i = 0 ; i < K + 2 ; ++i )
		for ( j = 0 ; j < K + 2 ; ++j )
			Cost[i][j] = INF;
	for ( i = 1 ; i <= K ; ++i )
		NewG[i].push_back( Source  ) , Cost[Source][i] = Dist[special[i]];
	if ( K )
	{
		for ( i = 1 ; i <= K ; ++i )
		{
			Dijkstra ( special[i]) ;
			for ( j = 1 ; j <= K ; ++j )
				if  ( i != j )
			NewG[j].push_back ( i) , Cost[i][j] = Dist[special[j]];
          NewG[Destination].push_back(  i  );
		  Cost[i][Destination] = Dist[N];
		}
		Hamilton(K+2);
	}
	else
		Answer = Dist[N];
	out << Answer << "\n";
	in.close();
	out.close();
	return 0 ;
}