Pagini recente » Cod sursa (job #2794136) | Cod sursa (job #2023059) | Cod sursa (job #2933154) | Cod sursa (job #781161) | Cod sursa (job #2764812)
#include<bits/stdc++.h>
using namespace std;
#define INIT ios_base :: sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define mp make_pair
#define pb push_back
#define ft first
#define sc second
#define ll long long
#define pii pair<int, int>
#define count_bits __builtin_popcount
//#define int ll
ifstream fin("adn.in"); ofstream fout("adn.out");
#define cin fin
#define cout fout
int N;
vector<string> v2, v;
//returns true if s2 is part of s1
int p[60003+10];
bool kmp(string &s1, string &s2, int p[]){
int n=s1.length(), m=s2.length();
bool ans=false;
p[0]=p[1]=0;
for(int i=2; i<=m; i++){
p[i]=p[i-1];
while( (p[i]>0) && (s2[p[i] ]!=s2[i-1]) ){
//p[i]=p[p[i] ]
p[i]=p[p[i]];
}
if(s2[p[i] ]==s2[i-1]){
p[i]++;
}
}
p[m+1]=0;
for(int i=1; i<=n; i++){
int j=i+m+1;
p[j]=p[j-1];
while( (p[j]>0) && (s2[p[j] ]!=s1[i-1]) ){
p[j]=p[p[j] ];
}
if(s2[p[j] ]==s1[i-1] ){
p[j]++;
}
if(p[j]==((int)s2.size()) ){ans=true;}
}
if(s1.length()==s2.length()){return false;}
return ans;
}
void eliminate(vector<string> v1, vector<string> &v2){
for(int i=0; i<v1.size(); i++){
bool is_prt=false;
for(int j=0; j<v1.size(); j++){
if(i==j){continue;}
is_prt|=kmp(v1[i], v1[j], p);
}
if(!is_prt){
v2.pb(v1[i]);
}
}
N=v2.size();
}
//building the graph
//{u, w}
int g[20][20];
void build(vector<string> &v){
for(int i=0; i<v.size(); i++){
for(int j=0; j<v.size(); j++){
if(i==j){continue;}
kmp(v[i], v[j], p);
g[i][j]=((int)v[j].length())-p[ (((int)v[j].length())+((int)v[i].length()) )+1 ];
}
}
}
//getting the ham-path/ maintain the seq
int dp[ (1ll<<18)-1 ][18];
pii anc[(1ll<<18)-1 ][18];
void build_dp(vector<string> &v){
N=v.size();
for(int i=0; i<N; i++){
dp[1ll<<i][i]=v[i].length();
anc[1ll<<i][i]={0, 0};
}
for(int b=1; b<(1ll<<N); b++){
for(int i=0; i<N; i++){
if( (b&(1ll<<i))>0 ){
if(dp[b][i]>0){
for(int j=0; j<N; j++){
//if(i==j){continue;}
//if( (b&(1ll<<j))>0 ){continue;}
if(dp[b|(1ll<<j) ][j]==0){
dp[b|(1ll<<j) ][j]=dp[b][i]+g[i][j];
anc[b|(1ll<<j) ][j]={b, i};
}
else{
if( (dp[b][i]+g[i][j] )<dp[b|(1ll<<j) ][j] ){
dp[b|(1ll<<j) ][j]=(dp[b][i]+g[i][j] );
anc[b|(1ll<<j) ][j]={b, i};
}
}
}
}
}
}
}
}
void build_ans(){
int mn=1e9;
pii pr={0, 0};
for(int i=0; i<N; i++){
if(dp[(1ll<<N)-1][i]<mn){
mn=dp[(1ll<<N)-1][i];
pr={ (1ll<<N)-1, i};
}
}
vector<int> ind;
while(pr!=mp(0,0) ){
ind.pb(pr.sc);
pr=anc[pr.ft ][pr.sc];
}
reverse(ind.begin(), ind.end());
cout<<v[ind[0] ];
//cout<<ind.size();
//cout<<ind[0]<<" ";
for(int i=1; i<ind.size(); i++){
//cout<<ind[i]<<" ";
for(int j= (((int)v[ind[i] ].length())-1-g[ind[i-1] ][ind[i] ]+1); j<v[ind[i] ].length(); j++ ){
cout<<v[ind[i] ][j];
}
}
}
int32_t main(){
INIT
//test
/*
string s2="abcd", s1="abaabeabcd";
int p[40]; memset(p, 0, sizeof(p));
kmp(s1, s2, p);
for(int i=1; i<=s1.size(); i++){
int j=i+1+((int)s2.size());
cout<<p[j]<<" ";
}
*/
cin>>N;
for(int i=1; i<=N; i++){
string S;
cin>>S;
v2.pb(S);
}
eliminate(v2, v);
//cout<<v.size()<<"\n";
build(v);
build_dp(v);
build_ans();
return 0;
}