Pagini recente » Cod sursa (job #1233870) | Cod sursa (job #2960245) | Cod sursa (job #2622744) | Cod sursa (job #2821726) | Cod sursa (job #1652941)
#include<fstream>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
ifstream fin( "adn.in" ); ofstream fout( "adn.out" );
const int lgmax = 30002;
const int inf = 1 << 30;
const int nmax = 18;
int n;
int pi[ lgmax + 1 ];
int c[ nmax + 1 ][ nmax + 1 ];
int d[ (1 << nmax) ][ nmax + 1 ], p[ (1 << nmax) + 1 ][ nmax + 1 ];
char r[ (1 << nmax) ][ nmax + 1 ];
vector< int > incl[ nmax + 1 ];
string s[ nmax + 1 ];
inline int adauga( int i, int x, int j ) {
return ( d[ i ][ x ] + ( int )s[ j ].size() - 1 - c[ x ][ j ] );
}
void kmp( int x, int y ) {
memset( pi, 0, sizeof( pi ) );
pi[ 1 ] = 0;
for( int i = 2; i < ( int )s[ x ].size(); ++ i ) {
int r = pi[ i - 1 ];
while ( r != 0 && s[ x ][ r + 1 ] != s[ x ][ i ] ) {
r = pi[ r ];
}
if ( s[ x ][ r + 1 ] == s[ x ][ i ] ) {
pi[ i ] = r + 1;
} else {
pi[ i ] = 0;
}
}
int r = 0;
for( int i = 1; i < ( int )s[ y ].size(); ++ i ) {
while ( r != 0 && s[ x ][ r + 1 ] != s[ y ][ i ] ) {
r = pi[ r ];
}
if ( s[ x ][ r + 1 ] == s[ y ][ i ] ) {
++ r;
}
if ( r == ( int )s[ x ].size() - 1 ) {
c[ y ][ x ] = r; return ;
incl[ y ].push_back( x );
}
}
c[ y ][ x ] = r;
}
void precalc() {
for( int i = 1; i <= n; ++ i ) {
for( int j = 1; j <= n; ++ j ) {
kmp( i, j );
}
}
}
void reconst( int st, int last ) {
if ( st == 0 ) {
return ;
}
int u = r[ st ][ last ];
if ( c[ last ][ u ] == ( int )s[ u ].size() - 1 ) {
reconst( st - (1 << (u - 1)), last );
} else {
reconst( st - (1 << (last - 1)), u );
for( int i = p[ st ][ last ]; i < ( int )s[ last ].size(); ++ i ) {
fout << s[ last ][ i ];
}
}
}
int main() {
fin >> n;
for( int i = 0; i < (1 << n); ++ i ) {
for( int j = 1; j <= n; ++ j ) {
d[ i ][ j ] = inf;
}
}
for( int i = 1; i <= n; ++ i ) {
fin >> s[ i ];
s[ i ] = "#" + s[ i ];
d[ (1 << (i - 1)) ][ i ] = ( int )s[ i ].size() - 1;
p[ (1 << (i - 1)) ][ i ] = 1;
}
precalc();
for( int i = 1; i < (1 << n); ++ i ) {
for( int j = 1; j <= n; ++ j ) {
if ( ( i & (1 << (j - 1)) ) == 0 ) {
continue;
}
int mask = i - (1 << (j - 1));
for( int x = 1; x <= n; ++ x ) {
if ( ( mask & (1 << (x - 1)) ) ) {
if ( d[ i ][ j ] > adauga( mask, x, j ) ) {
d[ i ][ j ] = adauga( mask, x, j );
p[ i ][ j ] = c[ x ][ j ] + 1;
r[ i ][ j ] = x;
}
}
}
for( vector< int >::iterator it = incl[ j ].begin(); it != incl[ j ].end(); ++ it ) {
int shp = i | (1 << (*it - 1));
if ( d[ shp ][ j ] > d[ i ][ j ] ) {
d[ shp ][ j ] = d[ i ][ j ];
p[ shp ][ j ] = ( int )s[ *it ].size();
r[ shp ][ j ] = *it;
}
}
}
}
int last = 0;
d[ (1 << n) - 1 ][ 0 ] = inf;
for( int i = 1; i <= n; ++ i ) {
if ( d[ (1 << n) - 1 ][ last ] > d[ (1 << n) - 1 ][ i ] ) {
last = i;
}
}
reconst( (1 << n) - 1, last );
fout << "\n";
fin.close();
fout.close();
return 0;
}