P6681
==Ambiguous Encoding。orz Wu_ren。
直接选两个拼成的字符串不好刻画,考虑增量。定义一对合法的字符串
容易发现,任何时刻
考虑如何转移:可以枚举一个当前最后模式串编号
然而这个转移是有环的,所以把 dp 变为 dis,转化为最短路做。答案即为
这题自然是可以轻松过的,但是 Ambiguous Encoding 看起来不行(
发现边权不超过
所以时间复杂度是
细节有一些,尤其注意当第
code:
点击查看代码
#define ID(i,j) ((i-1)*(m+1)+j+1)
int n,m,dis[N];
string s[N];bool vis[N];
priority_queue<pii> q;
int tot,head[N];
struct node{int to,nxt,cw;}e[M];
il void add(int u,int v,int w){e[++tot]={v,head[u],w},head[u]=tot;}
void Yorushika(){
scanf("%d%d",&n,&m);
rep(i,1,n)cin>>s[i];
rep(i,1,n){
int l=s[i].size();
rep(j,0,l-1){
rep(k,1,n){
int len=l-j;
if(k==i&&!j)continue;
if(s[k].size()>=len){
if(s[i].substr(j,len)==s[k].substr(0,len)){
int w=s[k].size()-len;
add(ID(i,len),ID(k,w),w);
}
}else{
int sz=s[k].size();
if(s[i].substr(j,sz)==s[k].substr(0,sz)){
int w=len-sz;
add(ID(i,len),ID(i,w),0);
}
}
}
}
}
mems(dis,0x3f);
rep(i,1,n){
int u=ID(i,s[i].size());
dis[u]=s[i].size(),q.push(Mp(-dis[u],u));
}
while(q.size()){
int u=q.top().se;q.pop();
if(vis[u])continue;
vis[u]=1;
go(i,u){
int v=e[i].to;
if(dis[v]<=dis[u]+e[i].cw)continue;
dis[v]=dis[u]+e[i].cw,q.push(Mp(-dis[v],v));
}
}
int ans=inf;
rep(i,1,n)ans=min(ans,dis[ID(i,0)]);
printf("%d\n",ans<1e9?ans:-1);
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}