KMP暴力求出next数组后
实际上是一个最短路问题,floyed搞一搞
然而会TLE
矩阵优化一下即可(倍增floyed) KMP在弱数据下可以AC。。正解请看其他人博客
# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <algorithm>
# include <string.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
return x * z;
}
int n, m, nxt[210][100010], len[210];
char s[210][100010];
struct Matrix{
ll a[210][210];
IL void Clear(){ Fill(a, 63); }
IL ll* operator [](RG int x){ return a[x]; }
IL Matrix operator *(RG Matrix &B){
RG Matrix C; C.Clear();
for(RG int i = 0; i <= n; i++)
for(RG int j = 0; j <= n; j++)
for(RG int k = 0; k <= n; k++)
C[i][k] = min(C[i][k], a[i][j] + B[j][k]);
return C;
}
} ans, edge;
int main(RG int argc, RG char* argv[]){
edge.Clear(); ans.Clear();
n = Read(); m = Read();
for(RG int i = 1; i <= n; i++)
scanf(" %s", s[i] + 1), len[i] = strlen(s[i] + 1);
for(RG int k = 1; k <= n; k++)
for(RG int i = 2, j = 0; i <= len[k]; i++){
while(j && s[k][j + 1] != s[k][i]) j = nxt[k][j];
if(s[k][j + 1] == s[k][i]) j++;
nxt[k][i] = j;
}
for(RG int x = 1; x <= n; x++){
edge[0][x] = len[x];
for(RG int y = 1; y <= n; y++)
for(RG int i = 2, j = 0; i <= len[x]; i++){
while(j && s[y][j + 1] != s[x][i]) j = nxt[y][j];
if(s[y][j + 1] == s[x][i]) j++;
if(i == len[x]) edge[x][y] = len[y] - j;
}
}
for(RG int i = 0; i <= n; i++) ans[i][i] = 0;
for(; m; m >>= 1, edge = edge * edge) if(m & 1) ans = ans * edge;
RG ll min_len = 1e18;
for(RG int i = 1; i <= n; i++) min_len = min(ans[0][i], min_len);
printf("%lld\n", min_len);
return 0;
}