hihocoder #1036 : Trie圖

第一次接觸Trie圖,參考了兩個文檔:
《Trie圖的構建、活用與改進-PPT》,裏面有一個例子可以參考。
《hihocoder#1036 : Trie圖》,題目本身對算法講解的很詳細。
trie圖是藉助了KMP、後綴的思想,對Trie樹做了改進,具體還是以題目本身的講解爲主了。
建圖過程最主要的有兩步:

  1. 計算當前節點的後綴節點。
  2. 爲當前節點補全後綴指針。

代碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <utility>
using namespace std;
typedef struct node{
    struct node * c[26],*pre;
    int cnt;
}node;
node *root,buf[1000010];
int bufsize=0;
inline node *getnode(){
    return buf+bufsize++;
}
char s[1000010];
int main()
{
    int n,i,j,k;
    scanf("%d",&n);
    memset(buf,0,sizeof(buf));
    root=buf+0;bufsize=1;
    root->pre=root;
    for(i=0;i<n;i++){
        scanf("%s",s);
        node *p=root;
        for(j=0;s[j];j++){
            k=s[j]-'a';
            if(p->c[k]==NULL)
                p->c[k]=getnode();
            p=p->c[k];
        }
        p->cnt=1;
    }
    queue<node*> que;
    for(i=0;i<26;i++){
        if(root->c[i]==NULL) root->c[i]=root;
        else{
            root->c[i]->pre=root;
            que.push(root->c[i]);
        }
    }
    while(!que.empty()){
        node *p=que.front();
        que.pop();
        p->cnt|=p->pre->cnt;
        for(i=0;i<26;i++){
            if(p->c[i]==NULL){
                p->c[i]=p->pre->c[i];
            }else{
                p->c[i]->pre=p->pre->c[i];
                que.push(p->c[i]);
            }
        }
    }
    scanf("%s",s);
    node *p=root;
    bool flag=false;
    for(i=0;s[i];i++){
        k=s[i]-'a';
        p=p->c[k];
        if(p->cnt>0) {
            flag=true;
            break;
        }
    }
    if(flag==true)
        printf("YES\n");
    else printf("NO\n");
    return 0;
}

題目鏈接

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述


掃碼關注,定期分享技術、算法類文章
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章