TLE #8 求调
查看原帖
TLE #8 求调
552688
clx201022楼主2024/5/18 15:26

https://www.luogu.com.cn/record/159408403

#include<bits/stdc++.h>
using namespace std;
class Aho_Corasick_Automaton
{
    public:
    std::vector<std::vector<unsigned> >tr;
    std::vector<unsigned>fail;
    std::vector<int>state;
    public:
    Aho_Corasick_Automaton()
    {reset();}
    unsigned push_new()
    {
        tr.push_back(std::vector<unsigned>(26,0));
        fail.push_back(0);
        state.push_back(0);
        return tr.size()-1;
    }
    void reset()
    {
        tr.clear();
        fail.clear();
        state.clear();
        push_new();
    }
    void insert(const std::string s,const int flag)
    {
        unsigned u=0;
        const unsigned slen=s.size();
        for(unsigned i=0;i<slen;i++)
        {
            if(tr[u][s[i]-'A']==0)tr[u][s[i]-'A']=push_new();
            u=tr[u][s[i]-'A'];
        }
        state[u]|=flag;//标记
    }
    void get_fail()
    {
        std::queue<unsigned>q;
        fail[0]=0;
        for(int i=0;i<26;i++)if(tr[0][i]!=0){fail[tr[0][i]]=0,q.push(tr[0][i]);}
        unsigned u;
        while(!q.empty())
        {
            u=q.front();
            q.pop();
            for(int i=0;i<26;i++)
            {
                if(tr[u][i]==0)
                {
                    tr[u][i]=tr[fail[u]][i];
                    continue;
                }
                fail[tr[u][i]]=tr[fail[u]][i];
                state[tr[u][i]]|=state[fail[tr[u][i]]];//标记传递
                q.push(tr[u][i]);
            }
        }
    }
}ac;
int n;string S;
bool vis[602][(1<<12)|1];
struct pack//打包
{unsigned place/*ac自动机中那个点*/;int data/*状态压缩*/;string s/*答案字符串*/;};
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>S;
        ac.insert(S,1<<i);
    }
    ac.get_fail();
    queue<pack>q;
    vis[0][0]=1;//防止重复访问
    q.push(pack{0,0,""});
    while(!q.empty())//bfs
    {
        const auto zzz1=q.front();
        q.pop();
        if(zzz1.data==(1<<n)-1)
        {
            cout<<zzz1.s<<endl;
            return 0;
        }//输出
        for(int i=0;i<26;i++)
        {
            auto zzz2=zzz1;
            zzz2.place=ac.tr[zzz2.place][i];//在 trie 图上移动
            zzz2.s+=('A'+(char)i);//答案多加一个字符串
            zzz2.data|=ac.state[zzz2.place];//碰到这些点
            if(!vis[zzz2.place][zzz2.data])
            {
                vis[zzz2.place][zzz2.data]=1;
                q.push(zzz2);//没访问过就入队
            }
        }//转移
    }
    return 0;
}
2024/5/18 15:26
加载中...