曾写过迭代加深搜索的方法,现在使用在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. SVN钩子说明

    post-commit在提交完成,成功创建版本之后执行该钩子,提交已经完成,不可更改,因此本脚本的返回值被忽略. post-lock对文件进行加锁操作之后执行该脚本 post-revprop-chan ...

  2. jquery数组内多维对象

    jquery数组内多维对象 var postData=[],obj,list; obj = !!obj ? obj : $('#dist_meici_checkinfo_form'); obj.fin ...

  3. Max Subsequence

    一个sequence,里面都是整数,求最长的subsequence的长度,使得这个subsquence的最大值和最小值相差不超过1. 比如[1,3,2,2,5,2,3,7]最长的subsequence ...

  4. pycharm 中 pep8 检查开启.

    pycharm pep8检查的开启,默认是暗黄色,我这里为了醒目给改成了黄色.

  5. 饿了么 openapi demo

    http://merchant.openapi.eleme.io/merchant.html#id215 class Program { static void Main(string[] args) ...

  6. poj4052

    题意:求一个文章(长度5.1e6)里面出现了多少个指定的模式串.重复出现只记一次.而且如果两个模式串都出现的情况下,一个是另一个的子串,则该子串不算出现过. 分析:AC自动机. 由于子串不算所以加一些 ...

  7. 解决 vs2010 联接sql 2005 时 报错未能加载文件或程序集“Microsoft.SqlServer.Management.Sdk.Sfc

    http://blogs.msdn.com/b/sqlnativeclient/archive/2008/05/30/sqlncli-msi-for-sql-server-2008.aspx 关键是这 ...

  8. pgpool介绍和安装经验

    Pgpool的介绍 一.介绍 是一个工作在PostgreSQL多服务器和PostgreSQL数据库客户端之间的中间件. 二.概念图 三.功能 连接池:pgpool -Ⅱ保存 连 接到PostgreSQ ...

  9. Cuckoo for Hashing_双哈希表

    问题 B: Cuckoo for Hashing 时间限制: 1 Sec  内存限制: 64 MB提交: 24  解决: 12[提交][状态][讨论版] 题目描述 An integer hash ta ...

  10. nyoj925_国王的烦恼_并查集

    国王的烦恼 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛.两个小岛间可能 ...