Tire在插入的过程中将所有经过的点向他连边
拓扑跑最长链(LIS也可做)
代码如下:
#include<cstring>
#include<cstdio>
#include<queue>
#define N 500020
using namespace std;
struct Node{
int x;
Node *ch[26];
Node():x(0){
for(int i=0;i<26;i++)
ch[i]=NULL;
}
}*root;
queue<int>q;
int cnt,top,n;
int fir[N],degree[N],f[N];
char s[N];
struct Edge{
int to,nex;
Edge(int _=0,int __=0):to(_),nex(__){}
}nex[N];
inline void add(int x,int y){
nex[++top]=Edge(y,fir[x]);
degree[y]++;
fir[x]=top;
}
inline void Insert(char *s){
Node *x=root;
int len=strlen(s+1);
cnt++;
for(int i=1;i<=len;i++){
if(x->ch[s[i]-'a']==NULL)
x->ch[s[i]-'a']=new Node;
x=x->ch[s[i]-'a'];
if(x->x) add(x->x,cnt);
}
if(!x->x) x->x=cnt;
}
inline int Toposort(){
for(int i=1;i<=cnt;i++){
f[i]=1;
if(!degree[i]) q.push(i);
}
int tmp=1;
while(!q.empty()){
int x=q.front();q.pop();
tmp=max(tmp,f[x]);
for(int i=fir[x];i;i=nex[i].nex){
degree[nex[i].to]--;
f[nex[i].to]=max(f[nex[i].to],f[x]+1);
if(!degree[nex[i].to]) q.push(nex[i].to);
}
}
return tmp;
}
int main(){
root=new Node;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
Insert(s);
}
printf("%d",Toposort());
return 0;
}