注意fail时怎么走。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-;
typedef long long lon;
const lon SZ=,SSZ=,APB=,one=;
const lon INF=0x7FFFFFFF,mod=;
lon n,m,mk[SZ],nex[SZ][APB],fail[SZ];
int cnt,endpos[SSZ],dst[SSZ][SSZ];
int dtb[SZ],dp[][SSZ],len[SSZ];
int ctn[SSZ][SSZ];
char ch[SZ];
string str[SSZ]; void add(int type,int id)
{
int cur=;
for(int i=;ch[i];++i)
{
int c=ch[i]-'';
if(!nex[cur][c])nex[cur][c]=++cnt;
cur=nex[cur][c];
}
if(type)mk[cur]=;
else endpos[id]=cur;
} void build()
{
queue<int> q;
q.push();
for(;q.size();)
{
int fr=q.front();
q.pop();
for(int i=;i<APB;++i)
{
int t=nex[fr][i];
if(t)
{
if(!fr)fail[t]=;
else
{
int u=fail[fr];
for(;u&&!nex[u][i];u=fail[u]);
u=nex[u][i];
fail[t]=u;
mk[t]|=mk[u];
}
q.push(t);
}
}
}
} void bfs(int x)
{
dtb[x]=;
queue<int> q;
q.push(x);
for(;q.size();)
{
int fr=q.front();
q.pop();
for(int i=;i<APB;++i)
{
int t=nex[fr][i];
if(t)
{
if(dtb[t]>dtb[fr]+&&!mk[t])
{
q.push(t);
dtb[t]=dtb[fr]+;
}
}
else
{
int u=fail[fr];
for(;u&&!nex[u][i];u=fail[u]);
t=nex[u][i];
if(dtb[t]>dtb[fr]+&&!mk[t])
{
q.push(t);
dtb[t]=dtb[fr]+;
}
}
}
}
} void init()
{
for(int i=;i<n;++i)
{
//cin>>ch+1;
scanf(" %s",ch+);
len[i]=strlen(ch+);
add(,i);
string tmp(ch+);
str[i]=tmp;
}
for(int i=;i<m;++i)
{
scanf(" %s",ch+);
add(,-);
}
build();
for(int i=;i<n;++i)
{
for(int j=;j<=cnt;++j)
dtb[j]=INF/;
int sta=;
bfs(endpos[i]);
for(int j=;j<n;++j)
{
dst[i][j]=dtb[endpos[j]];
}
}
} int dfs(int sta,int last)
{
//cout<<sta<<" "<<last<<endl;
if(dp[sta][last])return dp[sta][last];
else
{
int res=INF/;
for(int i=;i<n;++i)
{
if(ctn[last][i]&&(sta&(<<i)))sta^=<<i;
}
if(sta==)return len[last];
for(int i=;i<n;++i)
{
if(sta&(<<i))
{
res=min(res,dfs(sta,i)+dst[i][last]);
}
}
return dp[sta][last]=res;
}
} void work()
{
for(int i=;i<n;++i)
{
dp[<<i][i]=len[i];
}
int res=INF/;
for(int i=;i<n;++i)
{
for(int j=;j<n;++j)
{
if(str[i].find(str[j])!=-)ctn[i][j]=;
}
}
// for(int i=0;i<n;++i)
// {
// for(int j=0;j<n;++j)
// {
// cout<<ctn[i][j]<<" ";
// }cout<<endl;
// }
for(int i=;i<n;++i)
{
res=min(res,dfs((<<n)-,i));
//cout<<"i: "<<dfs((1<<n)-1,i)<<" "<<dst[0][1]<<" "<<dst[1][0]<<endl;
}
cout<<res<<endl;
} void release()
{
for(int i=;i<=cnt;++i)
{
mk[i]=;
memset(nex[i],,sizeof(nex[i]));
fail[i]=;
}
cnt=;
for(int i=;i<(<<n);++i)
{
memset(dp[i],,sizeof(dp[i]));
}
} int main()
{
//std::ios::sync_with_stdio(0);
//freopen("d:\\1.txt","r",stdin);
int casenum;
//memset(bel,-1,sizeof(bel));
//cin>>casenum;
//cout<<casenum<<endl;
//for(int time=1;time<=casenum;++time)
for(int time=;cin>>n>>m,n;++time)
{
init();
work();
release();
}
return ;
}

最新文章

  1. C# Winform学习---MDI窗体的设计,PictureBox控件(图片上一页下一页),Timer控件,MenuStrip控件
  2. UVA 11076 - Add Again(组合)
  3. 初始tornado框架
  4. 解决SurfaceView设置透明造成覆盖其他组件的替代方案
  5. poj 1703(带权并查集)
  6. 关于sql 外键的讨论。
  7. 4天html总结
  8. 2.XML高级用法
  9. CSS组件
  10. javascript 特殊的面向对象以及继承详解(入门篇)
  11. Linux 查看系统硬件信息[转]
  12. C语音下改变const变量的值的奇葩方法
  13. 【Python】HackBack(获取暴力破解服务器密码的IP来源)
  14. Web开发中需要了解的东西【转载】
  15. 插件PageHelper实现分页查询
  16. DNA甲基化检测服务
  17. DBA_实践指南系列2_Oracle Erp R12系统安装配置设定Setup(案例)
  18. gin入门
  19. JS 中根据iframe子页面自动iframe高度
  20. sudoers文件配置

热门文章

  1. Lintcode: Knight Shortest Path
  2. Django中上传图片---避免因图片重名导致被覆盖
  3. elasticsearch数据备份与sshfs建立共享文件
  4. Install rapyuta client on Raspberry Pi
  5. what?iView的DropDown没有element的split-button?提issure?等不及了,自己实现一个
  6. json转换导致金额失真问题解决
  7. Redmine(window7)安装
  8. 安装pip、numpy、sklearn
  9. java中的函数
  10. MIUI系统如何获取ROOT权限