链接

这题没想到怎么做,问了下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. 虚拟机设置静态ip

    最近学习hadoop,用到虚拟机来做分布式,由于hadoop要配置slave节点的主机名,所以需要修改hosts文件的ip地址和主机名的映射关系. 但是虚拟机每次重启后,ip地址都会变 ,这样每次都得 ...

  2. apk反编译、smali修改、回编译笔记

    最近下了一个apk程序,但是一启动会弹出一个流氓广告.这个广告不是原厂商加的,而是有人在原有apk程序的基础上,加了一个壳,让apk先启动他加的广告,再启动原来的程序,很恶心.于是想去掉它. 试了几个 ...

  3. C#使用ajaxForm进行上传图片

    <div class='imgOuter addImgBtn l_canshu' id='ImagePath1' value=''> <img src="../Images ...

  4. centos升级支持到C++11, gcc4.8.2

    升级到4.8[这个应该是目前最新的啦,不过网上查的话已经到5.2啦,感觉落后一点比较稳,当然还有就是这个版本是新的里面使用最多的] wget http://people.centos.org/tru/ ...

  5. 下拉列表select显示ng-options

    js中如何处理: it-equipment-list-maintenance-create-controller.js 'use strict'; myApp.controller( 'itEquip ...

  6. 记录一次项目中使用memcatch添加端口以及自动运行

    具体原因:多个项目同时使用一个memcatch服务情况需要分别为项目添加端口,如果只有一个项目使用则不需要去修改端口(memcatch有默认端口),当然已可以去修改默认端口. 下面我记录下我自己的使用 ...

  7. Netty5.x中新增和值得注意的点

    最近事情多,OneCoder折腾了好几天,总算翻译完成了. 翻译自官方文档:http://netty.io/wiki/new-and-noteworthy-in-5.x.html   该文档会列出在N ...

  8. 12月14日《奥威Power-BI销售计划填报》腾讯课堂开课啦

           2016年的最后一个月也过半了,新的一年就要到来,你是否做好了启程的准备?新的一年,有计划,有目标,有方向,才不至于迷茫.规划你的2017,新的一年,遇见更好的自己!        所以 ...

  9. Python Decorator 和函数式编程

    看到一篇翻译不错的文章,原文链接: Python Decorator 和函数式编程

  10. Java Map 集合类简介

      作者:Jack Shirazi 了解最常用的集合类型之一 Map 的基础知识以及如何针对您应用程序特有的数据优化 Map. 本文相关下载: · Jack 的 HashMap 测试 · Oracle ...