AC自动机,Tarjan(ZOJ 3784,String of Infinity)

来源:互联网 发布:2016年十大网络神曲 编辑:程序博客网 时间:2024/05/21 03:55

#include<bits/stdc++.h>using namespace std;const int maxn = 100010;const int maxc = 26;int MAXC;    int ch[maxn][maxc];    int val[maxn];    int sz;    int f[maxn];    vector<int>SET[maxn];    int pre[maxn];    int low[maxn];    int scc[maxn];    int dfs_clc;    int scc_cnt;    stack<int>s;    int vis[maxn];struct Trie{    void init()    {        sz=1;        memset(ch[0],0,sizeof(ch[0]));        val[0]=0;        char s[5];        s[1]='\0';        for(int c=0;c<MAXC;c++)        {            s[0]='a'+c;            insert(s);            val[sz-1]=0;        }    }    int idx(char c)    {        return c-'a';    }    void insert(char* s)    {        int l=strlen(s);        int u=0;        for(int i=0;i<l;i++)        {            int v=idx(s[i]);            if(!ch[u][v])            {                memset(ch[sz],0,sizeof(ch[sz]));                val[sz]=0;                ch[u][v]=sz++;            }            u=ch[u][v];        }        val[u]=1;    }    void getfail()    {        queue<int>q;        f[0]=0;        for(int c=0;c<MAXC;c++)        {            f[ch[0][c]]=0;            q.push(ch[0][c]);        }        while(!q.empty())        {            int r=q.front();            q.pop();            for(int c=0;c<MAXC;c++)            {                int u=ch[r][c];                if(!u)                {                    ch[r][c]=ch[f[r]][c];                    continue;                }                if(val[u]) continue;                int v=f[r];                while(v&&val[ch[v][c]]) v=f[v];                f[u]=ch[v][c];                val[u]|=val[f[u]];                if(!val[u]) q.push(u);            }        }    }    void dfs(int u)    {        pre[u]=low[u]=++dfs_clc;        s.push(u);        for(int c=0;c<MAXC;c++) if(!val[ch[u][c]])        {            int v=ch[u][c];            if(!pre[v])            {                dfs(v);                low[u]=min(low[u],low[v]);            }            else if(!scc[v]) low[u]=min(low[u],pre[v]);        }        if(pre[u]==low[u])        {            scc_cnt++;            while(1)            {                int x=s.top();                s.pop();                scc[x]=scc_cnt;                SET[scc_cnt].push_back(x);                if(x==u) break;            }        }    }    void handle()    {        for(int i=0;i<=sz;i++)        {            SET[i].clear();            pre[i]=0;            low[i]=0;            scc[i]=0;        }        dfs_clc=0;        scc_cnt=0;        while(!s.empty()) s.pop();        dfs(0);    }    int DFS(int u)    {        vis[u]=1;        int ret=0;        for(int c=0;c<MAXC;c++) if(scc[u]==scc[ch[u][c]])        {            int v=ch[u][c];            if(vis[v]) ret++;            if(!vis[v]) ret+=DFS(v);        }        return ret;    }    bool ok()    {        for(int i=0;i<=sz;i++) vis[i]=0;        handle();        for(int i=1;i<=scc_cnt;i++) if(DFS(SET[i][0])>1) return true;        return false;    }}trie;char str[1010];void solve(){    int N;    scanf("%d %d",&N,&MAXC);    trie.init();    while(N--)    {        scanf("%s",str);        trie.insert(str);    }    trie.getfail();    if(trie.ok()) puts("Yes");    else puts("No");}int main(){    int T;    scanf("%d",&T);    while(T--) solve();    return 0;}


0 0
原创粉丝点击