Cod sursa(job #803900)

Utilizator legionarulCorneliu Zelea Codreanu legionarul Data 28 octombrie 2012 15:26:37
Problema Ciclu hamiltonian de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
 # include <fstream>
 # include <cstring>
 # include <algorithm>
 # include <vector>
 
 # define dim 20
 # define inf 999999999
 # define pb push_back
 
 using namespace std;
 
 ifstream f("hamilton.in");
 ofstream g("hamilton.out");
 
 vector < int > a[ dim ];
 int dp[ 1 << dim ][ dim ];
 int cost[ dim ][ dim ];
 int n, m;
 int sol;
 
 void init_cost()
 {
	 int i, j;
	 
	 for ( i = 0 ; i < n ; i++ )
		 for ( j = 0 ; j < n ; j++ )
			 cost[ i ][ j ] = inf;
 }
 
 void init()
 {
	 int i, j;
	 for ( i = 0 ; i <= ( 1 << n ) ; i++ )
		 for ( j = 0 ; j < n ; j++ )
			 dp[ i ][ j ] = -1;
 }
 
 void citire()
 {
	 int i, x, y, z;
	 
	 f >> n >> m;
	 init_cost();
	 for ( i = 1 ; i <= m ; i++ )
	 {
		 f >> x >> y >> z;
		 a[ y ].pb( x );
		 cost[ x ][ y ] = z;
	 }
	 
 }
 
 int calc( int start, int conf, int final )
 {
	 int i;
	 
	 if ( dp[ conf ][ final ] == -1 )
	 {
		 dp[ conf ][ final ] = inf;
		 
		 for ( i = 0 ; i < a[ final ].size() ; i++ )
			 if ( conf & ( 1 << a[ final ][ i ] ) )
				 dp[ conf ][ final ] = min( dp[ conf ][ final ], calc( start, conf ^ ( 1 <<  final ), a[ final ][ i ] ) + cost[ a[ final ][ i ] ][ final ] );
	 }
	 
	 return dp[ conf ][ final ];
 }
 
 void rezolva()
 {
	 int i, j;
	 
	 sol = inf;
	 
	 for ( i = 0 ; i < n ; i++ )
	 {
		 init();
		 dp[ 1 << i ][ i ] = 0;
		 for ( j = 0 ; j < a[ i ].size() ; j++ )
			 sol = min( sol, calc( i, ( 1 << n ) - 1, a[ i ][ j ] ) + cost[ a[ i ][ j ] ][ i ] ); 
	 }
	 
	 if ( sol != inf )
		 g << sol << "\n";
	 else
		 g << "Nu exista solutie" << "\n";
 }
 
 int main()
 {
	 citire();
	 rezolva();
	 return 0;
 }