曾写过迭代加深搜索的方法,现在使用在AC自动上跑最短路的方法

dp[i][j]表示状态为到节点i,模式串是否包含的状态为j的最短串的长度,则状态转移方程为:

dp[nx][ny] = min(dp[x][y] + 1) , 其中nx为x后继结点,ny为从y转移过来的新状态,更新时加入队列

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<string>
using namespace std; int Hash[128];
typedef long long LL; const int N = 150, CH = 4, INF = 0x3F3F3F3F;
int n, cnt;
struct Trie{
Trie *next[CH];
Trie *fail;
int id;
}tree[N], *q[50000]; int chi[N][CH];
int sum[N];
int dp[N][1024];
bool inq[N][1024]; class ACauto{
private:
int nxt;
Trie *root; public:
ACauto(){
root = &tree[0];
nxt=0;
memset(&tree[0], 0, sizeof(Trie));
} void insert(string s, int id){
Trie *p = root;
for(int i = 0; i < s.size(); i++){
int c = Hash[s[i]];
if(!p -> next[c]){
memset(&tree[++nxt], 0, sizeof(Trie));
p -> next[c] = &tree[nxt];
p -> next[c] -> id = nxt;
}
p = p -> next[c];
}
sum[p->id] = 1 <<id;
} void build(){
int front = 0, rear = 0;
q[rear++] = root;
root -> fail = NULL;
while(front < rear){
Trie *cur = q[front++]; if(cur -> fail){
sum[cur->id] |= sum[cur->fail ->id];
} for(int i = 0; i < CH; i++){ Trie *son = cur -> next[i];
Trie *tp = (cur == root)? root: cur -> fail->next[i];
if(son == NULL){
cur -> next[i] = tp;
}else{
son -> fail = tp;
q[rear++] = son;
}
son = cur -> next[i];
chi[cur->id][i] = son->id;
}
}
} void solve(){
memset(dp, 0x3F, sizeof(dp));
memset(inq, 0, sizeof(inq));
queue<int> q;
dp[0][0] = 0;
inq[0][0] = 1;
int st = 1 << cnt;
q.push(0);
while(!q.empty()){
int u = q.front();
q.pop();
int x = u / st;
int y = u % st;
inq[x][y] = 0;
for(int i = 0 ; i < CH; i++){
int nx = chi[x][i], ny = y | sum[chi[x][i]];
if(dp[nx][ny] > dp[x][y] + 1){
dp[nx][ny] = dp[x][y] + 1;
if(!inq[nx][ny]){
q.push(nx * st + ny);
inq[nx][ny] = 1;
}
}
}
}
int ans = INF;
for(int i = 0; i <= nxt; i++){
ans = min(ans, dp[i][st - 1]);
}
printf("%d\n", ans); } }; char str[100];
int main(){
Hash['A'] = 0;
Hash['C'] = 1;
Hash['G'] = 2;
Hash['T'] = 3;
int t;
cin>>t;
while(t--){
int n;
cin>>n;
set<string> st;
for(int i = 0; i < n; i++){
string str;
cin>>str;
st.insert(str);
}
ACauto ac;
memset(sum, 0, sizeof(sum)); cnt = 0;
for(set<string>::iterator it = st.begin(); it != st.end(); it++){
ac.insert(*it, cnt++);
}
ac.build();
ac.solve();
} return 0;
}

  

POJ1699 HDU 1560 Best Sequence(AC自动机 最短路)的更多相关文章

  1. hdu 2896 病毒侵袭 ac自动机

    /* hdu 2896 病毒侵袭 ac自动机 从题意得知,模式串中没有重复的串出现,所以结构体中可以将last[](后缀链接)数组去掉 last[]数组主要是记录具有相同后缀模式串的末尾节点编号 .本 ...

  2. hdu 2896 病毒侵袭 AC自动机(查找包含哪些子串)

    病毒侵袭 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. HDU 1560 DNA sequence(DNA序列)

    HDU 1560 DNA sequence(DNA序列) Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K  ...

  4. HDU 5164Matching on Array(AC自动机)

    这是BC上的一道题,当时比赛没有做,回头看看题解,说是AC自动机,想着没有写过AC自动机,于是便试着抄抄白书的模板,硬是搞了我数个小时2000ms时限1800过了= = ! 这里就直接贴上BC的结题报 ...

  5. hdu 2222 Keywords Search ac自动机入门

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串. ...

  6. hdu 1560 DNA sequence(搜索)

    http://acm.hdu.edu.cn/showproblem.php?pid=1560 DNA sequence Time Limit: 15000/5000 MS (Java/Others)  ...

  7. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  8. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  9. poj_2778_DNA Sequence(AC自动机+矩阵)

    题目链接:poj_2778_DNA Sequence 题意: 有m个模式串,然后给你一个长度n,问你n长度的DNA序列有多少种不包含这m个模式串 题解: 这题显然要用AC自动机,将模式串的AC自动机建 ...

随机推荐

  1. IOS路线图

    存档,存档...

  2. ZJOIDay2T1 BB题解

    讲道理我是调不出来了... 考虑对序列按下标维护每个节点最后的树. 那么 改操作点 - 把一段连续的节点改父亲 加点/删点(注意拆成两个操作了) 插儿子 那么用seg维护一下下标, 用ETT维护Dep ...

  3. php foreach循环中unset后续的键值问题

    实例: $arr=array('a','b','c','d','e','f'); foreach($arr as $index=>$tmp){ echo $index.'=>'.$tmp. ...

  4. JAVA调用动态链接库DLL之JNative学习

    package com.ehfscliax; import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import ...

  5. NUI控件扩展

    摘要:NUI组件是公司新一代的前端开发框架,它精致优雅的前端编程模型,是大家能够,或者想接受学习它的重要原因,在使用它的时候,一定不免会想增加自己的控件,让别人也能够如此优雅的使用. 其实NUI的扩展 ...

  6. ubuntu14.04 archive sources.list

    deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse deb http://archive. ...

  7. PHP入门笔记

    PHP是一种创建动态交互性站点的强有力的服务器端脚本语言.PHP其代码可以直接嵌入HYML代码.PHP语法非常类似于Perl和C,常常搭配Apache一起使用. 1.PHP是指超文本预处理器(Hype ...

  8. Fraction to Recurring Decimal

    Given two integers representing the numerator and denominator of a fraction, return the fraction in ...

  9. C++基础知识面试精选100题系列(21-30)[C++ basics]

    [本文链接] http://www.cnblogs.com/hellogiser/p/100-interview-questions-of-cplusplus-basics-21-30.html [题 ...

  10. 基础01 dos命令

    常见的dos命令: 盘符:        进入指定的盘下面. 操作文件夹:                   dir                                   列出当前控制 ...