链接

这题没想到怎么做,问了下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. Spark在Yarn上运行Wordcount程序

    前提条件 1.CDH安装spark服务 2.下载IntelliJ IDEA编写WorkCount程序 3.上传到spark集群执行 一.下载IntellJ IDEA编写Java程序 1.下载IDEA ...

  2. <构建之法> 第四章 结对 读后感

    粗读 第四章主要讲的是关于结对合作的事项.大多数的软件开发都是团体性的,而合作的最小单位也就是两个人,这也是软件开发中的最佳实践.而结对中,我们能够更好的编写我们的代码,能够少一些担心,对自己的代码也 ...

  3. blcok的总结

    没有引用外部变量的block  为 __NSGlobalBlock__ 类型(全局block) MRC: 引用外部变量的block  为 __NSStackBlock__ 类型(栈区block)  栈 ...

  4. [转]Android View.onMeasure方法的理解

    转自:http://blog.sina.com.cn/s/blog_61fbf8d10100zzoy.html Android View.onMeasure方法的理解 View在屏幕上显示出来要先经过 ...

  5. Windows7中IIS简单安装与配置(详细图解)

    最近工作需要IIS,自己的电脑又是Windows7系统,找了下安装的方法,已经安装成功.在博客里记录一下,给需要的朋友,也是给自己留个备份,毕竟我脑子不是很好使. 一.首先是安装IIS.打开控制面板, ...

  6. Java Servlet(六):HttpServlet实现原理(jdk7+tomcat7+eclipse)

    本篇记录了HttpServlet的实现过程,主要讲述了如何依赖Servlet,GenericServlet实现的原理. HttpServlet实现过程:1.是一个Servlet,继承自GenericS ...

  7. 产品Backlog

    产品BACKLOG ID Name Imp Est How to demo Notes 1 界面(首页.订单.资料) 50 2 进入界面,选择需要的界面 使用分栏界面 2 首页里的功能按钮 40 6 ...

  8. csuoj 1503: 点到圆弧的距离

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1503 1503: 点到圆弧的距离 时间限制: 1 Sec  内存限制: 128 MB  Speci ...

  9. Pandas将中文数据集转换为数值类别型数据集

    一个机器学习竞赛中,题目大意如下,本文主要记录数据处理过程,为了模型训练,第一步需要将中文数据集处理为数值类别数据集保存. 基于大数据的运营商投诉与故障关联分析 目标:原始数据集是含大量中文的xls格 ...

  10. 优秀Python学习资源收集汇总(强烈推荐)

    Python是一种面向对象.直译式计算机程序设计语言.它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用縮进来定义语句块.与Scheme.Ruby.Perl ...