zoukankan      html  css  js  c++  java
  • 洛谷

    https://www.luogu.org/problemnew/show/P2444

    有点恶心,不太明白fail的意义。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    struct Trie{
        int nex[60010][2],fail[60010],End[60010];
        int root,L;
        int newnode(){
            /*for(int i=0;i<26;i++)
                nex[L][i]=-1;*/
            End[L++]=0;
            return L-1;
        }
    
        int cnt;
        void init(){
            L=0;
            cnt=0;
            memset(nex,-1,sizeof(nex));
            root=newnode();
        }
    
        void insert(char buf[]){
            int len=strlen(buf);
            int now=root;
            for(int i=0;i<len;i++){
                int &t=nex[now][buf[i]-'0'];
                if(t==-1)
                    t=newnode();
                now=t;
            }
            End[now]++;
            cnt++;
        }
    
        void build(){
            queue<int>Q;
            fail[root]=root;
            for(int i=0;i<2;i++){
                if(nex[root][i]==-1){
                    nex[root][i]=root;
                    //根节点没有对应的分支,还是必须回到根节点开始匹配
                }
                else{
                    //根节点的后继失配,先假定回到根节点匹配
                    fail[nex[root][i]]=root;
                    Q.push(nex[root][i]);
                }
            }
            while(!Q.empty()){
                int now=Q.front();
                Q.pop();
                for(int i=0;i<2;i++)
                    if(nex[now][i]==-1){
                        //某个节点没有这个对应的分支,它失配了,沿着失配边去到最近的有这个分支的边?
                        nex[now][i]=nex[fail[now]][i];
                    }
                    else{
                        fail[nex[now][i]]=nex[fail[now]][i];
                        Q.push(nex[now][i]);
                        //如果这个节点的fail指针指向的点是End,那么因为这个节点蕴含他的fail节点,所以他也是End
                        End[now]|=End[fail[now]];
                    }
            }
        }
    
    
        /*int query(char buf[]){
            int len=strlen(buf);
            int now=root;
            int res=0;
            for(int i=0;i<len;i++){
                now=nex[now][buf[i]-'0'];
                int temp=now;
                while(temp!=root&&End[temp]!=-1){
                    res+=End[temp];
                    End[temp]=-1;
                    temp=fail[temp];
                }
                //if(res==cnt)
                    //return res;
            }
            return res;
        }*/
    
        int vis[60005];
        int instack[60005];
        int find_circle(){
            memset(vis,0,sizeof(vis));
            memset(vis,0,sizeof(instack));
            return dfs(root);
        }
    
        int dfs(int id){
            instack[id]=1;
            vis[id]=1;
            for(int i=0;i<2;i++){
                if(instack[nex[id][i]]){
                    //该节点的下一条边在dfs栈中,是反向边
                    printf("TAK
    ");
                    exit(0);
                }
                if(vis[nex[id][i]]==0){
                    //不访问已经到过的表亲,表亲不可能成环
                    if(End[nex[id][i]]==0){
                        //下一个点不是病毒
                        dfs(nex[id][i]);
                    }
                }
            }
            instack[id]=0;
            return 0;
        }
    
    
    };
    
    char buf[100010];
    
    Trie ac;
    
    int n;
    void solve(){
        while(~scanf("%d",&n)){
            if(n==0)
                break;
            ac.init();
    
            for(int i=0;i<n;i++){
                scanf("%s",buf);
                ac.insert(buf);
            }
            ac.build();
            //scanf("%s",buf);
    
            if(ac.find_circle()==0){
                cout<<"NIE"<<endl;
            }
        }
    }
    
    int main(){
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
        //freopen("Yinku.out","w",stdout);
    #endif // Yinku
        solve();
    }
  • 相关阅读:
    探究操作系统的内存分配(malloc)对齐策略
    三十一个实用的小常识
    防止网页后退
    郁闷的一天
    脑袋不行
    家的开张
    猴子定律
    赴微软onsite!谁有C++/HTML/JavaScript开发工程师推荐?
    卡马克的求平方根函数代码的陷阱
    动作游戏自定义技能探讨
  • 原文地址:https://www.cnblogs.com/Yinku/p/10538026.html
Copyright © 2011-2022 走看看