HDU

来源:互联网 发布:数据库完整性约束类型 编辑:程序博客网 时间:2024/06/05 08:00

题目链接:点击打开链接

最近在练习AC自动机的专题,做完后搜题解看到大家都是用AC自动机加上DP做的。我是跑的bfs过的,虽然说方法不算太好,但是身为一股清流,抱着分享一种新的方法的态度写了这篇文章。不过话说回来,在AC自动机跑是一个状态的转移,在某个角度也可以看为一个图论的最短路变形的问题,我这里的写法和别人写法相比就相当于Dijstra相对于spfa~~~~~~

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <queue>using namespace std;typedef long long llt;const int N=1500;char DNAseq[50];char Repair[1500];int cnt[1100][1100];struct node_t{    node_t *son[4];    node_t *fail;    int flag;    int num;}Node[N];int toUsed;inline int find(char x){    if(x=='A') return 0;    if(x=='T') return 1;    if(x=='C') return 2;    return 3;}inline void init_Trie(){    toUsed=1;    memset(Node,0,sizeof(node_t));}inline node_t* _NewNode(){    memset(Node+toUsed,0,sizeof(node_t));    Node[toUsed].num=toUsed;    return Node+toUsed++;}void insert(char Word[]){    node_t *loc=Node;    for(int i=0;Word[i];i++)    {        int sn=find(Word[i]);        if(!loc->son[sn]) loc->son[sn]=_NewNode();        loc=loc->son[sn];    }    loc->flag=true;}void Build_AC(){    node_t *loc=Node;    loc->fail=NULL;    queue<node_t*> que;    while(!que.empty()) que.pop();    for(int i=0;i<4;i++)    {        node_t *p=loc->son[i];        if(p)        {            p->fail=loc;            que.push(p);        }    }    while(!que.empty())    {        node_t *father=que.front();        que.pop();        for(int i=0;i<4;i++)        {            node_t *p=father->son[i];            //v->son[i]其实和p等价            if(p)            {                node_t *v=father->fail;                while(v&&!v->son[i]) v=v->fail;                if(v==NULL) p->fail=Node;                else                {                    p->fail=v->son[i];                    if(v->son[i]->flag) p->flag=true;                }                que.push(p);            }        }    }}struct info{    int step,modify_time;    node_t *cur;    info(int _step=0,int _modify_time=0,node_t *_cur=NULL) {step=_step;modify_time=_modify_time;cur=_cur;}    bool operator < (const info& r)const {return modify_time>r.modify_time;}};//step :当前走到了字符串的哪一个位置//modify_time :当前修改了多少次//cur :当前走到了自动机的哪一个位置int bfs(){    memset(cnt,0x7f,sizeof(cnt));    int L=strlen(Repair);    priority_queue<info> que;    while(!que.empty()) que.pop();    cnt[0][0]=0;    que.push(info(0,0,Node));    while(!que.empty())    {        info tmp=que.top();        que.pop();        if(tmp.step==L) return tmp.modify_time;        for(int i=0;i<4;i++)        {            node_t *loc=tmp.cur;            while(loc&&loc->son[i]==NULL) loc=loc->fail;            loc=loc?loc->son[i]:Node;            if(loc->flag) continue;            int MOD=(find(Repair[tmp.step])==i)?tmp.modify_time:tmp.modify_time+1;            if(cnt[loc->num][tmp.step+1]>MOD)            {                cnt[loc->num][tmp.step+1]=MOD;                que.push(info(tmp.step+1,MOD,loc));            }        }    }    return -1;}int main(){    int N,nofkase=1;    while(scanf("%d",&N)&&N)    {        init_Trie();        for(int i=0;i<N;i++)        {            scanf("%s",DNAseq);            insert(DNAseq);        }        Build_AC();        scanf("%s",Repair);        printf("Case %d: %d\n",nofkase++,bfs());    }    return 0;}


原创粉丝点击