trie树

怒贴代码,算是学习trie树的写法了:#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#define N 30001
#define M 302
using namespace std;
struct node{ bool x; int sum; int next[26];};
struct edge{ int to,point,v;};
edge e[N];
node a[N];
char s[N][M];
int in[26],n,num,ans[N],cnt,tot;
bool flag;
void add(int u1,int v1){ e[++cnt].to=e[u1].point;e[u1].point=cnt;e[cnt].v=v1;}
void make_tree(char ch[]){
    int l=strlen(ch+1),now=0;
    for (int j=1;j<=l;j++){
int k=ch[j]-'a';
if (!a[now].next[k])  a[now].next[k]=++tot;
now=a[now].next[k];
    }
    a[now].x=1;
}


void init(){
scanf("%d\n",&n);
tot=0; cnt=0;
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++) scanf("%s",s[i]+1);
for (int i=1;i<=n;i++) make_tree(s[i]);
}


void mem(){
flag=0;
    memset(e,0,sizeof(e));
memset(in,0,sizeof(in));
}


void query(char ch[]){
int now=0,l=strlen(ch+1);
for (int j=1;j<=l;j++){
int k=ch[j]-'a';
if (a[now].x) { flag=1; return;}
for (int p=0;p<26;p++)
 if (p!=k&&a[now].next[p]){ add(k,p); in[p]++;}
now=a[now].next[k];
}
}


void topsort(){
queue<int>q;
for (int j=0;j<26;j++)
 if (!in[j]) q.push(j);
while (!q.empty()){
int k=q.front();
q.pop();
for (int p=e[k].point;p;p=e[p].to) {
  in[e[p].v]--; 
  if (!in[e[p].v]) q.push(e[p].v);}
}
for (int j=0;j<26;j++)
 if (in[j]) { flag=1; return;}
}


void DOIT(){
num=0;
for (int i=1;i<=n;i++){
mem();
    query(s[i]);
    topsort();
    if (!flag) ans[++num]=i;
}
}


void print(){
for (int i=1;i<=num;i++) printf("%s\n",s[ans[i]]+1);
}


int main(){
init();
DOIT();
    print();
return 0;
}

你可能感兴趣的:(trie树)