Pagini recente » Cod sursa (job #2067489) | Cod sursa (job #798679) | Cod sursa (job #632668) | Cod sursa (job #2420716) | Cod sursa (job #545175)
Cod sursa(job #545175)
#include <cstdio>
#include <cstring>
#define deb(n) fprintf(stderr,"%d ",(n));
#define debnl fprintf(stderr,"\n");
#define DN 20
#define DX 1<<19
#define DL 300005
#define MULT 0x3f3f3f3f
int n,cost[DN][DN],lg[DN],pi[DL],newn[DN],m,
dp[DX][DN],pre[DX][DN];
char seq[DN][DL];
void cp(int x) {
for(int k=0,i=2; i<=lg[x]; ++i) {
for(;k && seq[x][k+1]!=seq[x][i];k=pi[k]);
if(seq[x][k+1]==seq[x][i]) ++k;
pi[i]=k;
}
}
int kmp(int x, int y, int &cost) {
int ret=0;
for(int k=0,i=1;i<=lg[y]; ++i) {
for(;k && seq[x][k+1]!=seq[y][i];k=pi[k]);
if(seq[x][k+1]==seq[y][i]) ++k;
if(k==lg[x]) ret=1;
cost=k;
}
return ret;
}
int viz[DN];
void afis(int x,int y) {
if(0==y) return;
afis(pre[y][x],y^(1<<(x-1)));
for(int i=cost[newn[pre[y][x]]][newn[x]]+1;i<=lg[newn[x]]; ++i) printf("%c",seq[newn[x]][i]);
}
int main()
{
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
scanf("%d",&n);
for(int i=1; i<=n; ++i) {
scanf("%s",seq[i]+1);
lg[i]=strlen(seq[i]+1);
}
for(int i=1; i<=n; ++i) {
cp(i);
for(int j=1; j<=n; ++j) if(i!=j) {
// cp(i);
int cst=0;
if(kmp(i,j,cst)) viz[i]=1;
//deb(cst)
cost[j][i]=cst;
}
}
for(int i=1; i<=n; ++i) if(0==viz[i]) newn[++m]=i;
//hamilton
memset(dp,MULT,sizeof(dp));
for(int i=1; i<=m; ++i) dp[1<<(i-1)][i]=lg[newn[i]];
for(int i=0; i<(1<<m); ++i) for(int j=1;j<=m; ++j) if(i&(1<<(j-1)))
for(int k=1; k<=m; ++k) if(0==(i&(1<<(k-1)))) if(dp[i^(1<<(k-1))][k]>dp[i][j]+lg[newn[k]]-cost[newn[j]][newn[k]]) {
dp[i^(1<<(k-1))][k]=dp[i][j]+lg[newn[k]]-cost[newn[j]][newn[k]];
pre[i^(1<<(k-1))][k]=j;
}
//deb(dp[(1<<m)-1][3])
int rez=MULT,start;
for(int i=1; i<=m; ++i) if(dp[(1<<m)-1][i]<rez) {
rez=dp[(1<<m)-1][i];
start=i;
}
afis(start,(1<<m)-1);
return 0;
}