Pagini recente » Cod sursa (job #1590904) | Cod sursa (job #2371135) | Cod sursa (job #679592) | Cod sursa (job #1018611) | Cod sursa (job #2113593)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int inf=1e9;
char sir[19][60010];
int cost[20][20],sol[20],d[(1<<18)+10][20],tata[(1<<18)+10][20],d1[60010],lung[20],v1[20],vaz[20],nod1[20],poz[20];
vector<pair<int,int>> v[20];
int solve(int a,int b)
{
int l1=lung[a];
int l2=lung[b];
int l=min(l1,l2);
for(int i=l1+1;i<=l1+l2;i++) sir[a][i]=sir[b][i-l1];
int k=0;
memset(d1,0,sizeof(d1));
for(int i=2;i<=l1+l2;i++)
{
while(k!=0 && sir[a][i]!=sir[a][k+1]) k=d1[k];
if(sir[a][i]==sir[a][k+1]) k++;
d1[i]=k;
}
for(int i=l1+l2;i>=l1*2;i--) if(d1[i]==l1) {cost[a][b]=0;break;}
k=l1+l2;
while(1)
{
if(d1[k]<=l) return l1-d1[k];
k=d1[k];
}
}
int main()
{
freopen("adn.in","r",stdin);
freopen("adn.out","w",stdout);
int n;
scanf("%d\n",&n);
for(int i=0;i<n;i++) {gets(sir[i]+1);lung[i]=strlen(sir[i]+1);}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) cost[i][j]=inf;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j)
{
int c=solve(j,i);
cost[i][j]=min(cost[i][j],c);
}
for(int i=0;i<n;i++)
if(vaz[i]==0)
{
int p=0,ll=0;
for(int j=0;j<n;j++)
if(i!=j && cost[i][j]==0)
{
if(lung[j]>lung[i]) {p=1;break;}
else if(lung[j]==lung[i]) {v1[++ll]=j;}
}
if(p==1) {vaz[i]=1;continue;}
for(int j=1;j<=ll;j++) vaz[v1[j]]=1;
}
int ll=0;
for(int i=0;i<n;i++)
if(vaz[i]==0) {poz[i]=ll;nod1[ll]=i;ll++;}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j && vaz[i]==0 && vaz[j]==0) v[poz[i]].push_back({poz[j],cost[i][j]});
n=ll;
int lim=(1<<n);
for(int mask=1;mask<lim;mask++)
for(int i=0;i<n;i++)
d[mask][i]=inf;
for(int i=0;i<n;i++) {d[(1<<i)][i]=lung[nod1[i]];tata[(1<<i)][i]=-1;}
for(int mask=1;mask<lim;mask++)
for(int i=0;i<n;i++)
if(mask&(1<<i))
for(int j=0;j<v[i].size();j++)
{
int vec=v[i][j].first,c=v[i][j].second;
if(mask&(1<<vec)) continue;
if(d[mask][i]+c<d[mask+(1<<vec)][vec])
{
d[mask+(1<<vec)][vec]=d[mask][i]+c;
tata[mask+(1<<vec)][vec]=i;
}
}
int ans=1e9,l=0;
for(int i=0;i<n;i++) ans=min(ans,d[lim-1][i]);
for(int i=0;i<n;i++)
if(d[lim-1][i]==ans)
{
int nod=i,mask=lim-1;
sol[++l]=nod1[nod];
while(tata[mask][nod]!=-1)
{
int nod2=nod;
nod=tata[mask][nod];
sol[++l]=nod1[nod];
mask-=(1<<nod2);
}
break;
}
int p=1;
for(int i=l;i>=1;i--)
{
int l1=lung[sol[i]];
for(int j=p;j<=l1;j++) printf("%c",sir[sol[i]][j]);
p=lung[sol[i-1]]-cost[sol[i]][sol[i-1]]+1;
}
return 0;
}