曾写过迭代加深搜索的方法,现在使用在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. Python 类变量和成员变量

    Python 类变量和成员变量 类与对象的方法 我们已经讨论了类与对象的功能部分,现在我们来看一下它的数据部分.事实上,它们只是与类和对象的名称空间 绑定 的普通变量,即这些名称只在这些类与对象的前提 ...

  2. centos终端中mysql中文显示乱码的处理

    http://stackoverflow.com/questions/3513773/change-mysql-default-character-set-to-utf-8-in-my-cnfhttp ...

  3. 一个简单的log

    #pragma once #include <windows.h> #include <process.h> class CLogger { public: static CR ...

  4. yum服务器搭建(深入理解yum工作原理)

    作者:firefoxbug 时间:July 27, 2014 分类:Linux 前言 在前面一篇rpm包制作描述了rpm的打包过程,这篇文章主要讲述yum的工作原理. yum 运行原理 yum的工作需 ...

  5. 【Networking】k8s容器网络 && golang相关

    Bookmarks flannel/proxy.c at master · coreos/flannel kubernetes/kubernetes: Production-Grade Contain ...

  6. 64位系统运行32位Oracle程序解决方案

    Attempt to load Oracle client libraries threw BadImageFormatException. This problem will occur when ...

  7. ffmpeg-20160527-git-bin

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  8. SAP ALV显示并打印(非OO方式)

    *&---------------------------------------------------------------------* *& Report  Z_SD_CPF ...

  9. linux 解压缩

    tar f 使用档案名字,这个参数是最后一个参数,后面只能接档案名 c 建立压缩档案 x 解压 t 查看内容 r 向压缩归档文件末尾追加文件 u 更新原压缩包中的文件 z 有gzip属性的 j 有bz ...

  10. poj 1102.LC-Display 解题报告

    题目链接:http://poj.org/problem?id=1102 题目意思:就是根据给出的格式 s 和 数字 n,输出数值 n 的 LCD 显示.数值 n 的每个数字要占据 s + 2 列 和 ...