hdu 2222(AC自动机)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn = 1e7 + 5;
  4 const int MAX = 10000000;
  5 int cnt;
  6 struct node{
  7     node *next[26];
  8     node *fail;
  9     int sum;
 10 };
 11 node *root;
 12 char key[70];
 13 node *q[MAX];
 14 int head,tail;
 15 node *newnode;
 16 char pattern[maxn];
 17 int N;
 18 void Insert(char *s)
 19 {
 20     node *p = root;
 21     for(int i = 0; s[i]; i++)
 22     {
 23         int x = s[i] - 'a';
 24         if(p->next[x] == NULL)
 25         {
 26             newnode=(struct node *)malloc(sizeof(struct node));
 27             for(int j=0;j<26;j++) newnode->next[j] = 0;
 28             newnode->sum = 0;newnode->fail = 0;
 29             p->next[x]=newnode;
 30         }
 31         p = p->next[x];
 32     }
 33     p->sum++;
 34 }
 35 void build_fail_pointer()
 36 {
 37     head = 0;
 38     tail = 1;
 39     q[head] = root;
 40     node *p;
 41     node *temp;
 42     while(head < tail)
 43     {
 44         temp = q[head++];
 45         for(int i = 0; i <= 25; i++)
 46         {
 47             if(temp->next[i])
 48             {
 49                 if(temp == root)
 50                 {
 51                     temp->next[i]->fail = root;
 52                 }
 53                 else
 54                 {
 55                     p = temp->fail;
 56                     while(p)
 57                     {
 58                         if(p->next[i])
 59                         {
 60                             temp->next[i]->fail = p->next[i];
 61                             break;
 62                         }
 63                         p = p->fail;
 64                     }
 65                     if(p == NULL) temp->next[i]->fail = root;
 66                 }
 67                 q[tail++] = temp->next[i];
 68             }
 69         }
 70     }
 71 }
 72 void ac_automation(char *ch)
 73 {
 74     node *p = root;
 75     int len = strlen(ch);
 76     for(int i = 0; i < len; i++)
 77     {
 78         int x = ch[i] - 'a';
 79         while(!p->next[x] && p != root) p = p->fail;
 80         p = p->next[x];
 81         if(!p) p = root;
 82         node *temp = p;
 83         while(temp != root)
 84         {
 85            if(temp->sum >= 0)
 86            {
 87                cnt += temp->sum;
 88                temp->sum = -1;
 89            }
 90            else break;
 91            temp = temp->fail;
 92         }
 93     }
 94 }
 95 int main()
 96 {
 97     int T;
 98     scanf("%d",&T);
 99     while(T--)
100     {
101         root=(struct node *)malloc(sizeof(struct node));
102         for(int j=0;j<26;j++) root->next[j] = 0;
103         root->fail = 0;
104         root->sum = 0;
105         scanf("%d",&N);
106         for(int i = 1; i <= N; i++)
107         {
108             scanf("%s",key);
109             Insert(key);
110         }
111         scanf("%s",pattern);
112         cnt = 0;
113         build_fail_pointer();
114         ac_automation(pattern);
115         printf("%d\n",cnt);
116     }
117     return 0;
118 }

大佬的博客:https://blog.csdn.net/creatorx/article/details/71100840

 

hdu6208

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<queue>
  4 #include<string>
  5 #include<iostream>
  6 const int maxn = 100005;
  7 using namespace std;
  8 
  9 int n;
 10 int nxt[maxn][30],FAIL[maxn],edd[maxn],root,L;
 11 int mark[maxn];
 12 
 13 int newnode()
 14 {
 15     for(int i=0;i<26;i++)
 16         nxt[L][i] = -1;//节点连接的边初始化为-1
 17     edd[L]=0;
 18     mark[L]=0;
 19     return L++;
 20 }
 21 
 22 void init()
 23 {
 24     L=0;
 25     root=newnode();
 26 }
 27 
 28 void insert(char buf[],int l)//trie树的建立
 29 {
 30     int now=root;
 31     for(int i=0;i<l;i++)
 32     {
 33         if(nxt[now][buf[i]-'a']==-1)
 34             nxt[now][buf[i]-'a']=newnode();
 35         now=nxt[now][buf[i]-'a'];
 36     }
 37     edd[now]++;
 38 }
 39 
 40 void build()//建立ac自动机
 41 {
 42     queue<int>que;
 43     for(int i=0;i<26;i++)
 44     {
 45         if(nxt[root][i]==-1)
 46             nxt[root][i]=root;
 47         else                                 //若有连边则将节点加入队列 ,并将FAIL指针指向root
 48         {
 49             FAIL[nxt[root][i]]=root;
 50             que.push(nxt[root][i]);
 51         }
 52     }
 53     while(!que.empty())
 54     {
 55         int now=que.front();
 56         que.pop();
 57         for(int i=0;i<26;i++)
 58         {
 59             if(nxt[now][i]==-1)            //若无连边,则将该边指向当前节点FAIL指针指向的相应字符连接的节点
 60                 nxt[now][i]=nxt[FAIL[now]][i];
 61             else                            //若有连边,则将儿子节点的FAIL指针指向当前节点FAIL指针指向相应字符接的节点
 62             {
 63                 FAIL[nxt[now][i]]=nxt[FAIL[now]][i];
 64                 que.push(nxt[now][i]); //加入队列继续遍历
 65             }
 66         }
 67     }
 68 }
 69 
 70 int query(char buf[],int l)
 71 {
 72     int now=root;
 73     int res=0;
 74     for(int i=0;i<l;i++)
 75     {
 76         now=nxt[now][buf[i]-'a'];
 77         int temp=now;
 78         while(temp!=root&&mark[temp]==0)//根据题目要求改变形式
 79         {
 80             res+=edd[temp];
 81             edd[temp]=0;
 82             mark[temp]=1;
 83             temp=FAIL[temp];
 84         }
 85     }
 86     return res; //在这里返回的是匹配到的模式串的数量
 87 }
 88 
 89 char buf[maxn],ans[maxn];
 90 string A[maxn];
 91 
 92 int main()
 93 {
 94     int T;
 95     scanf("%d",&T);
 96     while(T--)
 97     {
 98         scanf("%d",&n);
 99         init();
100         int ma=0;
101         for(int i=0;i<n;i++)
102         {
103             scanf("%s",buf);
104             int l=strlen(buf);
105             if(ma<l)
106             {
107                 ma=l;
108                 strcpy(ans,buf);
109             }
110             insert(buf,l);
111         }
112         build();
113         int sum = query(ans,ma);
114         if(sum == n) printf("%s\n", ans);
115         else puts("No");
116     }
117 }

 

posted @ 2018-05-15 19:23  ouyang_wsgwz  阅读(160)  评论(0编辑  收藏  举报