Pagini recente » Cod sursa (job #2537509) | Cod sursa (job #3273594) | Cod sursa (job #1282622) | Cod sursa (job #2165232) | Cod sursa (job #1001677)
#include <fstream>
#include <vector>
#include <utility>
using namespace std;
ifstream fin("adn.in");
ofstream fout("adn.out");
string s[20];
int m[20][20],pi[30001],series[20];
int hamilton[1<<18][18],hamiltonpath[1<<18][18];
int n,cnt;
bool contained[20];
void KMP (string s, int ind)
{
int n = s.length();
int k = -1;
pi[0] = -1;
for (int i=1; i<n; ++i)
{
while (k > -1 && s[k+1] != s[i]) k = pi[k];
if (s[k+1]==s[i]) ++k;
pi[i] = k;
}
}
void draw_edge (int ind1, int ind2)
{
int n1 = s[ind1].length();
int n2 = s[ind2].length();
int k = -1;
for (int i=0; i<n1; ++i)
{
while (k > -1 && s[ind2][k+1] != s[ind1][i]) k = pi[k];
if (s[ind2][k+1] == s[ind1][i]) ++k;
if (k==n2-1)
{
contained[ind2]=1;
return;
}
}
m[ind1][ind2] = k+1;
}
int main()
{
fin>>n;
for (int i=0; i<n; ++i)
{
fin>>s[i];
KMP (s[i],i);
}
for (int i=0; i<n; ++i)
{
KMP (s[i],i);
for (int j=0; j<n; ++j)
{
if (i!=j)
draw_edge (j,i);
}
}
int nr = (1<<n);
for (int i=0; i<nr; ++i)
for (int j=0; j<n; ++j)
{
hamilton[i][j]=-1;
hamiltonpath[i][j]=-1;
}
for (int i=0; i<n; ++i)
if (contained[i]) cnt+= (1<<i);
for (int j=0; j<n; ++j)
{
if (contained[j]) continue;
hamilton[(1<<j)+cnt][j]=0;
hamiltonpath[(1<<j)+cnt][j]=j;
}
for (int i=1; i<nr; ++i)
{
for (int j=0; j<n; ++j)
{
if (hamilton[i][j]==-1 || contained[j]) continue;
for (int k=0; k<n; ++k)
{
if ((i | (1<<k))!=i && contained[k]==0)
{
if (hamilton[i][j] + m[j][k] > hamilton [i | (1<<k)][k])
{
hamilton [i | (1<<k)][k] = hamilton[i][j] + m[j][k];
hamiltonpath [i | (1<<k)][k] = j;
}
}
}
}
}
int i,j=0,maxv=0;
for (i=0; i<n; ++i)
if (hamilton[nr-1][i] > maxv)
{
maxv = hamilton[nr-1][i];
j = i;
}
i = nr-1;
int t=n;
while (i!=cnt)
{
series[--t] = j;
int temp = j;
j = hamiltonpath[i][temp];
i = i-(1<<temp);
}
fout<<s[series[t]];
for (int i=t+1; i<n; ++i)
{
int k = m[series[i-1]][series[i]];
for (int j=k; j<s[series[i]].length(); ++j)
fout<<s[series[i]][j];
}
}