链接

这题没想到怎么做,问了下p队长,大悟。。

先求出任意两串的在trie树上的最短距离,期间是不能走到不合法的地方,我是用spfa求得,在更新和加入节点时判断一下是不是合法位置。

求出最短距离之后,找出一条从0出发遍历所有串的最短距离,可以dp出,dp[i][j]表示当前状态以节点j串结尾的最短距离。

枚举一下最后结尾的为哪一个串时距离最短。

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 60010
#define M 10010
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
const int child_num = ;
int w[][];
bool vis[N];
int dis[N];
class AC
{
private:
int ch[N][child_num];
int fail[N];
int Q[N];
int val[N],vv[N];
int id[];
int sz ;
int po[];
int dp[][];
public:
void init()
{
fail[] = ;
id[''] = ;
id[''] = ;
}
void reset()
{
memset(ch[],,sizeof(ch[]));
memset(val,,sizeof(val));
memset(vv,,sizeof(vv));
sz=;
}
void insert(char *a ,int key)
{
int p = ;
for( ; *a ; a++)
{
int d = id[*a];
if(ch[p][d]==)
{
memset(ch[sz],,sizeof(ch[sz]));
ch[p][d] = sz++;
}
p = ch[p][d];
}
if(key!=-)
{
val[p] = <<(key-);
po[key] = p;
}
else
{
vv[p] = ;
}
}
void construct()
{
int i,head=,tail = ;
for(i = ; i < child_num ; i++)
if(ch[][i])
{
fail[ch[][i]] = ;
Q[tail++] = ch[][i];
}
while(head!=tail)
{
int u = Q[head++];
vv[u]|=vv[fail[u]];
val[u]|=val[fail[u]];
for(i = ;i < child_num ; i++)
{
if(ch[u][i])
{
fail[ch[u][i]] = ch[fail[u]][i];
Q[tail++] = ch[u][i];
}
else ch[u][i] = ch[fail[u]][i];
}
}
}
int spfa(int st,int ed)
{
int i;
memset(vis,,sizeof(vis));
for(i = ; i <= sz ;i++)
dis[i] = INF;
dis[st] = ;
vis[st] = ;
queue<int>q;
q.push(st);
while(!q.empty())
{
int u = q.front();
q.pop();
for(i = ; i < child_num; i++)
{
int v = ch[u][i];
if(vv[v]) continue;
dis[v] = min(dis[v],dis[u]+);
//if(st == 4&&ed==8)
//cout<<v<<" "<<dis[v]<<" "<<u<<endl;
if(!vis[v])
{
vis[v] = ;
q.push(v);
}
}
}
return dis[ed];
}
void find_dis(int n)
{
int i,j;
po[] = ;
for(i = ; i <= n ;i++)
{
w[][i] = w[i][] = spfa(,po[i]);
//cout<<w[0][i]<<endl;
}
for(i = ; i <= n; i++)
for(j = ; j <= n ;j++)
{
w[i][j] = spfa(po[i],po[j]);
// cout<<w[i][j]<<" "<<i<<" "<<j<<endl;
}
}
void work(int n)
{
int i,j,g;
for(i = ; i < (<<n) ; i++)
for(j = ;j <= n; j++)
dp[i][j] = INF;
dp[][] = ;
for(i = ;i < (<<n) ; i++)
{
for(j = ;j <= n ;j++)
{
for(g = ; g <= n ;g++)
{
if((<<(g-))&i) continue;
dp[i+(<<(g-))][g] = min(dp[i+(<<(g-))][g],dp[i][j]+w[j][g]);
}
}
}
int ans = INF;
for(i = ; i <= n ; i++)
ans = min(ans,dp[(<<n)-][i]);
cout<<ans<<endl;
}
}ac;
char vir[],re[];
int main()
{
int n,m,i;
ac.init();
while(scanf("%d%d",&n,&m)&&n&&m)
{
ac.reset();
for(i = ; i <= n ;i++)
{
scanf("%s",re);
ac.insert(re,i);
}
while(m--)
{
scanf("%s",vir);
ac.insert(vir,-);
}
ac.construct();
ac.find_dis(n);
ac.work(n);
}
return ;
}

hdu3247Resource Archiver(ac自动机+spfa)的更多相关文章

  1. HDU3247 Resource Archiver (AC自动机+spfa+状压DP)

    Great! Your new software is almost finished! The only thing left to do is archiving all your n resou ...

  2. hdu3247Resource Archiver (AC自动机+最短路+状压dp)

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submis ...

  3. 【hdu3247-Resource Archiver】位压DP+AC自动机+SPFA

    题意:给定n个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. (2 <= n <= 10, 1 <= m <= 1000) 题 ...

  4. hdu_3247_Resource Archiver(AC自动机+bfs+TSP)

    题目链接:hdu_3247_Resource Archiver 题意: 有n个资源串,m个病毒串,现在要将所有的资源串整合到一个串内,并且这个串不能包括病毒串,问最短的串长为多少 题解: 将资源串和病 ...

  5. HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-3247 Resource Archiver Time Limit: 20000/10000 MS (Java/Others)  ...

  6. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

  7. HDU 3247 Resource Archiver (AC自动机+BFS+状压DP)

    题意:给定 n 个文本串,m个病毒串,文本串重叠部分可以合并,但合并后不能含有病毒串,问所有文本串合并后最短多长. 析:先把所有的文本串和病毒都插入到AC自动机上,不过标记不一样,可以给病毒标记-1, ...

  8. 【HDU3247】 Resource Archiver(DP+AC自动机+最短路)

    Resource Archiver Time Limit: 10000MS   Memory Limit: 100000KB   64bit IO Format: %I64d & %I64u ...

  9. HDU-3247 Resource Archiver(AC自动机+BFS)

    Description Great! Your new software is almost finished! The only thing left to do is archiving all ...

随机推荐

  1. nodejs 初入

    nodejs 模块路径 1.内置模块 如果传递给require函数的是NodeJS内置模块名称,不做路径解析,直接返回内部模块的导出对象,例:require('http'). 2. nodejs  支 ...

  2. JSONP使用笔记

    JSONP JSONP是实现跨域GET请求的一种方法, 原理上利用script标签可以动态加载JS文件, 将不同源站点的JSON数据加载到本网站来,如果给定回调函数,将回调函数名传递到服务器端, 在服 ...

  3. RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布

    RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布 全新体验.全新感觉.2015钜献! 继上个版本“RDIFramework.NET V2.8版本发布”5 ...

  4. url传值错误

    ValueError at /add/ invalid literal for int() with base 10: ''6'' Request Method: GET Request URL: h ...

  5. 解决 No resource found that matches the given name (at 'icon' with value '@drawable/icon') 问题

    对新解决方案Xamarin的Android项目在项目属性 换图标后 会出现 No resource found that matches the given name (at 'icon' with ...

  6. [Effective JavaScript 笔记]第65条:不要在计算时阻塞事件队列

    第61条解释了异步API怎样帮助我们防止一段程序阻塞应用程序的事件队列.使用下面代码,可以很容易使一个应用程序陷入泥潭. while(true){} 而且它并不需要一个无限循环来写一个缓慢的程序.代码 ...

  7. python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容

    python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...

  8. maven常见错误

    摘要: 1.Java-maven异常-cannot be cast to javax.servlet.Filter 报错  tomcat 启动后先将tomcat/lib目录下的jar包全部读入内存,如 ...

  9. CSS3 笔记一(Rounded Corners/Border Images/Backgrounds)

    CSS3 Rounded Corners The border-radius property is a shorthand property for setting the four border- ...

  10. POJ 2420:A Star not a Tree?

    原文链接:https://www.dreamwings.cn/poj2420/2838.html A Star not a Tree? Time Limit: 1000MS   Memory Limi ...