Pagini recente » Cod sursa (job #232331) | Cod sursa (job #180191) | Cod sursa (job #1473479) | Cod sursa (job #330720) | Cod sursa (job #867897)
Cod sursa(job #867897)
#include <fstream>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 19
#define MAXDIM 31000
#define INF 0x3f3f3f3f
ifstream fin("adn.in");
ofstream fout("adn.out");
int N, pre[MAXDIM], len[MAXN], inside[MAXN], dist[MAXN][MAXN], prev[1 << (MAXN - 1)][MAXN], rez[1 << (MAXN - 1)][MAXN];
char sir[MAXN][MAXDIM];
void read() {
fin >> N; fin.get();
for (int i = 1; i <= N; ++i) {
fin.getline(sir[i] + 1, MAXDIM);
len[i] = strlen(sir[i] + 1);
}
}
void make_prefix(int x) {
pre[1] = 0;
for (int i = 2, k = 0; i <= len[x]; ++i) {
while (k > 0 && sir[x][k + 1] != sir[x][i])
k = pre[k];
if (sir[x][k + 1] == sir[x][i])
++k;
pre[i] = k;
}
}
void doKMP(int x, int y) {
int k = 0;
for (int i = 1; i <= len[y]; ++i) {
while (k > 0 && sir[x][k + 1] != sir[y][i])
k = pre[k];
if (sir[x][k + 1] == sir[y][i])
++k;
if (k == len[x]) {
inside[y] = 1;
break;
}
}
dist[y][x] = len[x] - k;
}
void do_graph() {
for (int i = 1; i <= N; ++i) {
make_prefix(i);
for (int j = 1; j <= N; ++j)
if (i != j && !inside[i])
doKMP(i, j);
}
}
void solve_next(int conf, int last) {
for (int k = 1; k <= N; ++k)
if (k != last && !inside[k])
if (rez[conf + (1 << (k - 1))][k] > rez[conf][last] + dist[last][k]) {
rez[conf + (1 << (k - 1))][k] = rez[conf][last] + dist[last][k];
prev[conf + (1 << (k - 1))][k] = last;
}
}
void solve() {
memset(rez, INF, sizeof(rez));
for (int i = 1; i <= N; ++i)
if (!inside[i])
rez[1 << (i - 1)][i] = len[i];
for (int i = 1; i < (1 << N); ++i) {
for (int j = 1; j <= N; ++j)
if (rez[i][j] != INF)
solve_next(i, j);
}
}
void print_recursion(int conf, int last, int pot) {
if (prev[conf][last] != 0)
print_recursion (conf - (1 << (last - 1)), prev[conf][last], len[last] - dist[prev[conf][last]][last]);
for (int i = 1; i <= len[last] - pot; ++i)
fout << sir[last][i];
}
void print() {
int maxCONF = (1 << N) - 1;
int maxDIM = INF, maxPOZ;
for (int i = 1; i <= N; ++i)
if (inside[i])
maxCONF -= 1 << (i - 1);
for (int i = 1; i <= N; ++i) {
if (rez[maxCONF][i] < maxDIM) {
maxDIM = rez[maxCONF][i];
maxPOZ = i;
}
}
print_recursion(maxCONF, maxPOZ, 0);
}
int main() {
read();
do_graph();
solve();
print();
return 0;
}