SAP_AC自动机_后缀数组模版集合
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
网络流增广路25行SAP算法KMR风格代码
int now[N];//点的当前弧
int pre[N];//点的前驱
int d[N];//点的标号
int num[N];//标号为i的个数
int his[N];//历史流量
int top[N],c[M],prev[M],end[M];//邻接表
主程序
Int Shortest_Augment_Path(){
int i=s,j,k,flow=MaxLongint,ret=0;
for(int i=1;i<=n;++i)now[i]=top[i];num[0]=n;
while(d[s]!=n){
his[i]=flow;
for(k=now[i];k;k=prev[k])if(c[k]&&d[j=end[k]]+1==d[i])break;找标号点
if(k){
if(c[now[i]=k] pre[j]=i;i=j;记录前驱 if(i==t){ 找到一条增广路 ret+=flow; while(i!=s)i=pre[i],c[now[i]]-=flow,c[now[i]^1]+=flow;修改路上的流量 flow=MaxLongint; } }else{ if(--num[d[i]]==0)break;d[i]=n;断层优化 for(k=now[i]=top[i];k;k=prev[k])if(c[k]&&d[end[k]]+1 d[i]=d[end[now[i]=k]]+1; ++num[d[i]]; if(i!=s)i=pre[i],flow=his[i]; } } return ret; } 此程序为本人在借鉴了前人代码的基础上经过压行修改后出炉的,代码只有25行,充分照顾了不想多写代码的童鞋。 AC自动机建立17行模版。 Trie 树组,假设只有26个字母。int son[N][26]; 转移函数。int f[N][26]; 失败指针。int Pi[N]; bfs队列Int que[N]; Trie树的建立 void Insert(char *s) { int len=strlen(s),c,now=0; for(int i=0;i { c=s[i]-'a'; if(!son[now][c])son[now][c]=++tot; now=son[now][c]; } } AC自动机的建立。 void Aho_Corasick() 对,这是AC自动机的英文。 { for(int head=1,tail=1,x,u,k,i;head<=tail;++head) //head头指针,tail尾指针。 { u=que[head]; for(i=0;i<26;++i) if(son[u][i])f[u][i]=que[++tail]=son[u][i]; if(!u)continue; //若当前点为root,退出。 for(i=0;i<26;++i) { k=Pi[u]; while(k&&!son[k][i])k=Pi[k]; //算出转移函数。 if((x=son[u][i]))Pi[x]=son[k][i]; else f[u][i]=son[k][i]; } } } 此AC自动机的代码是我在借鉴前人的基础上做了点改动后写的。标准风格是17行,KMR风格是14行。 后缀数组20行模版 Int c[N]; \\基数排序的数组。 Int rank[N];\\排名数组。 Int tmp[N];\\辅助排名数组。 Int SA[N];\\众所周知的Suffix_Array数组。 Int s[N];\\原字符串。 主程序 void say(int *rank,int *tmp) { rep(i,n)c[s[i]-'a']++;//基数排序 for(int i=0;i<26;i++)c[i]+=c[i-1]; rep(i,n)sa[c[s[i]-'a']--]=i; rep(i,n)rank[sa[i]]=rank[sa[i-1]]+1-(s[sa[i]]==s[sa[i-1]]); for(int len=1;len { memset(c,0,sizeof(c)); rep(i,n)++c[rank[i+len]];//按第二关键字进行第一次基数排序 rep(i,n)c[i]+=c[i-1]; rep(i,n)tmp[c[rank[i+len]]--]=i; memset(c,0,sizeof(c)); rep(i,n)++c[rank[i]];//按第一关键字进行第二次基数排序 rep(i,n)c[i]+=c[i-1]; down(i,n)sa[c[rank[tmp[i]]]--]=tmp[i];//按第一次排序后的结果处理SA数组 rep(i,n)tmp[sa[i]]=tmp[sa[i-1]]+1-//将排名暂时存在tmp中 (rank[sa[i]]==rank[sa[i-1]]&&rank[sa[i]+len]==rank[sa[i-1]+len]); swap(rank,tmp);//这里用了指针优化,省去了memcpy。 } }