码迷,mamicode.com
首页 > 其他好文 > 详细

【Trie图】BZOJ3940-[Usaco2015 Feb]Censoring

时间:2016-08-14 19:12:20      阅读:209      评论:0      收藏:0      [点我收藏+]

标签:

【题目大意】

有一个匹配串和多个模式串,现在不断删去匹配串中的模式串,求出最后匹配串剩下的部分。

【思路】

众所周知,KMP的题往往对应着一道AC自动机quq。本题同BZOJ3942(KMP),这里改成AC自动机即可。

我一开始写了原始的AC自动机,写挂了。后来思考了一下,应当用Trie图,机智地1A。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 const int MAXN=100000+50;
  8 char str[MAXN];
  9 int n,cnt;
 10 struct ACauto
 11 {
 12     ACauto* next[26];
 13     ACauto* fail;
 14     int id;
 15     int sign;
 16     ACauto()
 17     {
 18         for (int i=0;i<26;i++) next[i]=NULL;
 19         fail=NULL;
 20         id=++cnt;
 21         sign=0;
 22     }
 23 };
 24 
 25 ACauto* rt=new ACauto();
 26 
 27 void insert(char* s,ACauto* rt)
 28 {
 29     ACauto* tmp=rt;
 30     for (int i=0;s[i];i++)
 31     {
 32         int index=s[i]-a;
 33         if (tmp->next[index]==NULL)
 34             tmp->next[index]=new ACauto();
 35         tmp=tmp->next[index];
 36     }
 37     tmp->sign=strlen(s);
 38 }
 39 
 40 void buildfail(ACauto* rt)//这里我们建立Trie图而不是Trie树的AC自动机 
 41 {
 42     queue<ACauto*> que;
 43     que.push(rt);
 44     while (!que.empty())
 45     {
 46         ACauto* head=que.front();que.pop();
 47         for (int i=0;i<26;i++)
 48         {
 49             if (head->next[i]==NULL)
 50             {
 51                 if (head==rt) head->next[i]=rt;
 52                     else head->next[i]=head->fail->next[i];
 53             }
 54             else
 55             {
 56                 if (head==rt) head->next[i]->fail=rt;
 57                     else
 58                     {
 59                         head->next[i]->fail=head->fail->next[i];
 60                         //if (head->next[i]->fail->sign) head->next[i]->sign=head->next[i]->fail->sign;/*注意!*/
 61                     }
 62                 que.push(head->next[i]);
 63             }
 64         }
 65     }
 66 } 
 67 
 68 void init()
 69 {
 70     cnt=0;
 71     scanf("%s",str);
 72     scanf("%d",&n);
 73     for (int i=0;i<n;i++)
 74     {
 75         char s[MAXN];
 76         scanf("%s",s);
 77         insert(s,rt);
 78     }
 79     buildfail(rt);
 80 }
 81 
 82 void solve()
 83 {
 84     ACauto* a[MAXN];
 85     char stack[MAXN];
 86     int top=0;
 87     a[top]=rt;
 88     for (int i=0;str[i];i++)
 89     {
 90         ACauto* j=a[top];
 91         stack[++top]=str[i];
 92         int index=str[i]-a;
 93         a[top]=j->next[index];
 94         if (a[top]->sign) top-=a[top]->sign;
 95     }
 96     stack[top+1]=\0;
 97     puts(stack+1);
 98 }
 99 
100 int main()
101 {
102     init();
103     solve();
104     return 0;
105 } 

 

【Trie图】BZOJ3940-[Usaco2015 Feb]Censoring

标签:

原文地址:http://www.cnblogs.com/iiyiyi/p/5770594.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!