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();
    }
  • 相关阅读:
    uva 147 Dollars
    hdu 2069 Coin Change(完全背包)
    hdu 1708 Fibonacci String
    hdu 1568 Fibonacci
    hdu 1316 How Many Fibs?
    poj 1958 Strange Towers of Hanoi
    poj 3601Tower of Hanoi
    poj 3572 Hanoi Tower
    poj 1920 Towers of Hanoi
    筛选法——素数打表
  • 原文地址:https://www.cnblogs.com/Yinku/p/10538026.html
Copyright © 2011-2022 走看看