Pagini recente » Cod sursa (job #2938673) | Cod sursa (job #1645555) | Cod sursa (job #2536224) | Cod sursa (job #681497) | Cod sursa (job #1048331)
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int kmans = 650000;
int n, valid[20], size[20], dp[18][1 << 18], dad[18][1 << 18];
char gv[20][30005];
int graph[20][20];
int t[30005];
void prefix(int x){
for(int i = 2; i <= size[x]; ++i){
int p = i - 1;
do{
p = t[p];
if(gv[x][i] == gv[x][p + 1]){
t[i] = p + 1;
break;
}
}while(p);
}
}
int dps[30005];
void checkem(int x, int y){
memset(dps, 0, sizeof(dps));
memset(t, 0, sizeof(t));
prefix(y);
for(int i = 1; i <= size[x]; ++i){
int p = dps[i - 1];
if(gv[x][i] == gv[y][p + 1]){
dps[i] = p + 1;
if(dps[i] == size[y])
valid[y] = 0;
continue;
}
if(p == 0)
continue;
do{
p = t[p];
if(gv[x][i] == gv[y][p + 1]){
dps[i] = p + 1;
break;
}
}while(p);
if(dps[i] == size[y])
valid[y] = 0;
}
graph[x][y] = size[y] - dps[size[x]];
}
int main(){
freopen("adn.in", "r", stdin);
freopen("adn.out", "w", stdout);
scanf("%d\n", &n);
for(int i = 1; i <= n; ++i){
gets(gv[i] + 1);
valid[i] = 1;
size[i] = strlen(gv[i] + 1);
}
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j) if(j != i)
checkem(i, j);
vector<int> good;
for(int i = 1; i <= n; ++i)
if(valid[i])
good.push_back(i);
int lim = 1 << good.size();
memset(dp, 1337, sizeof(dp));
for(int i = 0; i < good.size(); ++i){
dp[i][1 << i] = size[good[i]];
dad[i][1 << i] = -1;
}
for(int i = 0; i < lim; ++i)
for(int j = 0; j < good.size(); ++j) if(dp[j][i] <= kmans)
for(int k = 0; k < good.size(); ++k)
if(!(i & (1 << k)))
if(dp[k][i + (1 << k)] > dp[j][i] + graph[good[j]][good[k]]){
dp[k][i + (1 << k)] = dp[j][i] + graph[good[j]][good[k]];
dad[k][i + (1 << k)] = j;
}
int mins = kmans, wh = -1;
for(int i = 0; i < good.size(); ++i)
if(dp[i][lim - 1] < mins){
mins = dp[i][lim - 1];
wh = i;
}
vector<int> ord;
int p = lim - 1, aux;
for(int i = 0; i < good.size(); ++i){
ord.push_back(good[wh]);
aux = wh;
wh = dad[wh][p];
p = p - (1 << aux);
}
int last = 1;
for(int i = ord.size() - 1; i >= 0; --i){
for(int j = last; j <= size[ord[i]]; ++j)
printf("%c", gv[ord[i]][j]);
if(i != 0)
last = size[ord[i - 1]] - graph[ord[i]][ord[i - 1]] + 1;
}
return 0;
}