AC自动机入门题(HDU 2222 + HDU 2896)

AC自动机学习资料:http://blog.csdn.net/niushuai666/article/details/7002823

AC自动机模板:http://www.cnblogs.com/kuangbin/p/3164106.html

我这两个入门题完全是用的Kuangbin大神的板子敲的…..


http://acm.hdu.edu.cn/showproblem.php?pid=2896

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <queue>
#include <set>
using namespace std;

const int MAXN = 550*220;
struct Trie
{
        int next[MAXN][128], fail[MAXN], end[MAXN];
        int root,L;

        int newnode()
        {
                for(int i=0; i<128; i++)
                        next[L][i] = -1;
                end[L++] = -1;
                return L-1;
        }
        void init()
        {
                L = 0;
                root = newnode();
        }
        void insert(char buf[],int id)
        {
                int len = strlen(buf);
                int now = root;
                for(int i=0; i<len ; i++)
                {
                        if(next[now][buf[i]]==-1) 
                                next[now][buf[i]] = newnode();
                        now = next[now][buf[i]];
                }
                end[now] =  id;
        }
        void built()
        {
                queue<int> Q;
                fail[root] = root;
                for(int i=0; i<128;i++)
                {
                        if(next[root][i]==-1)
                                next[root][i] = root;
                        else 
                        {
                                fail[next[root][i]] = root;
                                Q.push(next[root][i]);
                        }
                }

                while(!Q.empty())
                {
                        int now = Q.front();
                        Q.pop();

                        for(int i=0; i<128;i++)
                        {
                                if(next[now][i] == -1)
                                        next[now][i] = next[fail[now]][i];
                                else 
                                {
                                        fail[next[now][i]] = next[fail[now]][i];
                                        Q.push(next[now][i]);
                                }
                        }
                }

        }

        bool  query(char buf[],int id)
        {
             set<int>s; s.clear();
             int len = strlen(buf);
             int now = root;
             for(int i=0; i<len;i++)
             {
                     now = next[now][buf[i]];
                     int tmp = now;
                     while( tmp!=root)
                     {
                             if(end[tmp]!=-1)
                                 s.insert(end[tmp]);
                             tmp = fail[tmp];
                     }
             }
             if(s.size()==0) return false;
             else 
             {
                     printf("web %d:",id);
                     for(set<int>::iterator it = s.begin();it!=s.end();it++)
                     {
                             printf(" %d",*it);
                     }
                     printf("\n");
                     return true;
             }
        }
};
Trie ac;
char s[10100];
int main()
{
        int n;
        scanf("%d\n",&n);
        ac.init();
        for(int  i=1; i<=n;i++)
        {
                gets(s);
                ac.insert(s,i);
        }
        ac.built();
        int m;
        scanf("%d\n",&m);
        int cnt = 0;
        for(int i=1;i<=m;i++)
        {
                gets(s);
                if(ac.query(s,i))  cnt++;
        }
        printf("total: %d\n",cnt);
        return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=2222

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int LEN = 1000000 + 100;
const int MAXN = 50 * 10000 + 100;
struct Trie
{
        int next[MAXN][26],fail[MAXN],end[MAXN];
        int root,L;

        int newnode()
        {
                for(int i=0;i<26;i++)
                        next[L][i] = -1;
                end[L++] = 0;
                return L-1;
        }

        void init()
        {
                L = 0;
                root = newnode();
        }

        void insert(char buf[])
        {
                int len = strlen(buf);
                int now = root;
                for(int i=0; i<len; i++)
                {
                        if(next[now][buf[i]-'a'] == -1)
                                next[now][buf[i]-'a'] = newnode();
                        now = next[now][buf[i]-'a'];
                }
                end[now]++;
        }

        void built()
        {
                queue<int> que;
                fail[root] = root;
                for(int i=0; i<26;i++)
                {
                        if(next[root][i] == -1)
                                next[root][i] = root;
                        else 
                        {
                                fail[next[root][i]] = root;
                                que.push(next[root][i]);
                        }
                }
                while(!que.empty())
                {
                        int now = que.front();
                        que.pop();

                        for(int i=0; i<26; i++)
                        {
                                if(next[now][i]==-1)
                                        next[now][i] = next[fail[now]][i]; 
                                else
                                {
                                        fail[next[now][i]]  = next[fail[now]][i];
                                        que.push(next[now][i]);
                                }
                        }
                }
        }

        int query(char buf[])
        {
                int len = strlen(buf);
                int now = root;
                int res = 0;
                for(int i=0; i<len; i++)
                {
                        now = next[now][buf[i]-'a'];
                        int tmp = now;
                        while(tmp!=root)
                        {
                                res += end[tmp];
                                end[tmp] = 0;
                                tmp = fail[tmp];
                        }
                }
                return res;
        }
};
Trie ac;
char buf[LEN];
int main()
{
        int T;
        scanf("%d",&T);
        while(T--)
        {
                int n;
                scanf("%d",&n);
                ac.init();
                while(n--)
                {
                        scanf(" %s",buf);
                        ac.insert(buf);
                }
                ac.built();
                scanf(" %s",buf);
                printf("%d\n",ac.query(buf));
        }
        return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值