Pagini recente » Cod sursa (job #1223834) | Cod sursa (job #1575590) | Cod sursa (job #2452585) | Cod sursa (job #266663) | Cod sursa (job #1576947)
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
ifstream f("adn.in");
ofstream g("adn.out");
const int NMax = 20;
const int oo = 0x3f3f3f3f;
vector <int> G[NMax],Sol;
int N,M,C[NMax][NMax],DP[262150][NMax];
pair<int,int> Link[262150][NMax];
int Len[NMax];
char Matrix[NMax][30005];
int ind,Z[2*30005];
bool Ok[NMax];
char Str[2*30005];
int Array[NMax];
void Read()
{
f>>N;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
C[i][j]=oo;
f.get();
for(int i=0;i<N;i++)
{
f.getline(Matrix[i]+1,30005);
Len[i]=strlen(Matrix[i]+1);
}
}
int newPosition(int k,int start)
{
int result=0;
while(Str[start]==Str[k] && k<=ind)
{
result++;
start++;
k++;
}
return result;
}
void precalcZ()
{
int i;
Z[1]=ind;
int L=0,R=0;
for(int k=2;k<=ind;k++)
{
if(k>R)
{
Z[k]=newPosition(k,1);
L=k;R=k+Z[k]-1;
}
else
{
int aux=k-L+1;
if(Z[aux]<R-k+1)
Z[k]=Z[aux];
else
{
int poz=R+1+newPosition(R+1,R-k+2);
Z[k]=poz-k;R=poz-1;L=k;
}
}
}
}
void eliminate()
{
for(int i=0;i<N;i++)
Ok[i]=1;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
if(i==j)
continue;
ind=0;
for(int k=1;k<=Len[i];k++)
Str[++ind]=Matrix[i][k];
for(int k=1;k<=Len[j];k++)
Str[++ind]=Matrix[j][k];
precalcZ();
for(int k=Len[i]+1;k<=ind;k++)
if(Z[k]>=Len[i])
{
Ok[i]=0;
break;
}
if(Ok[i]==0)
break;
}
int cnt=0;
for(int i=0;i<N;i++)
if(Ok[i]==1)
Array[cnt++]=i;
N=cnt;
}
void precalcC()
{
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
if(i==j)
continue;
ind=0;
for(int k=1;k<=Len[Array[j]];k++)
Str[++ind]=Matrix[Array[j]][k];
for(int k=1;k<=Len[Array[i]];k++)
Str[++ind]=Matrix[Array[i]][k];
precalcZ();
int number=0;
for(int k=ind-Len[Array[j]]+2;k<=ind;k++)
if(Z[k]+k-1==ind)
{
number=ind-k+1;
break;
}
C[i][j]=Len[Array[j]]-number;
}
}
void Solve()
{
for(int i=1;i<(1<<N);i++)
for(int j=0;j<N;j++)
DP[i][j]=oo;
for(int i=0;i<N;i++)
DP[(1<<i)][i]=Len[Array[i]];
for(int conf=1;conf<(1<<N);conf++)
for(int i=0;i<N;i++)
{
if(DP[conf][i]!=oo)
continue;
if((conf & (1<<i)))
for(int j=0;j<N;j++)
{
if(i==j)
continue;
int Vecin=j;
if((conf & (1<<Vecin)))
if(DP[conf][i]>DP[conf^(1<<i)][Vecin]+C[Vecin][i])
{
DP[conf][i]=DP[conf^(1<<i)][Vecin]+C[Vecin][i];
Link[conf][i]=make_pair((conf^(1<<i)),Vecin);
}
}
}
int Min=oo,point=0;
int a=(1<<N)-1;
for(int i=0;i<N;i++)
if(DP[a][i]<Min)
{
Min=DP[a][i];
point=i;
}
int b=point;
Sol.push_back(b);
while(Link[a][b]!=make_pair(0,0))
{
int x=a,y=b;
a=Link[x][y].first;b=Link[x][y].second;
Sol.push_back(b);
}
for(int i=Sol.size()-1;i>=0;i--)
{
int pos=Sol[i];
int len;
if(i==Sol.size()-1)
len=1;
else
len=Len[Array[Sol[i]]]-C[Sol[i+1]][Sol[i]]+1;
for(int j=len;j<=Len[Array[Sol[i]]];j++)
g<<Matrix[Array[Sol[i]]][j];
}
g<<"\n";
}
int main()
{
Read();
eliminate();
precalcC();
Solve();
return 0;
}