ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

luoguP4112 [HEOI2015]最短不公共子串 SAM,序列自动机,广搜BFS

2019-07-14 09:54:24  阅读:299  来源: 互联网

标签:dian luoguP4112 SAM int BFS pair 序列 自动机 first


luoguP4112 [HEOI2015]最短不公共子串

链接

luogu
loj

思路

子串可以用后缀自动机,子序列可以用序列自动机。
序列自动机是啥,就是能访问到所有子序列的自动机。
每个点记录下一个字母最近出现的位置。不过我这里构造是\(O(n^2)\)。
然后进行bfs进行广搜就行了。
注意vis[][]剪枝,要不TLE。

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2000+7;
int n,m;
struct node {
    int len,fa,ch[26];
}dian[4][N<<1];
int las[4]={1,1,1,1},tot[4]={1,1,1,1};
void add(int c,int who) {
    int p=las[who];int np=las[who]=++tot[who];
    dian[who][np].len=dian[who][p].len+1;
    for(;p&&!dian[who][p].ch[c];p=dian[who][p].fa) dian[who][p].ch[c]=np;
    if(!p) dian[who][np].fa=1;
    else {
        int q=dian[who][p].ch[c];
        if(dian[who][q].len==dian[who][p].len+1) dian[who][np].fa=q;
        else {
            int nq=++tot[who];
            dian[who][nq]=dian[who][q];
            dian[who][nq].len=dian[who][p].len+1;
            dian[who][q].fa=dian[who][np].fa=nq;
            for(;p&&dian[who][p].ch[c]==q;p=dian[who][p].fa)
                dian[who][p].ch[c]=nq;
        }
    }
}
struct edge{char s[N];}a,b;
int vis[N<<1][N<<1],flag;
void bfs(int T_T,int QwQ) {
    queue<pair<pair<int,int>,int> > q;
    q.push(make_pair(make_pair(1,1),1));
    while(!q.empty()) {
        pair<pair<int,int>,int> u=q.front();
        node lj1=dian[T_T][u.first.first],lj2=dian[QwQ][u.first.second];
        q.pop();
        for(int i=0;i<26;++i) {
            if(lj1.ch[i]&&!lj2.ch[i])
                return printf("%d\n",u.second),void();
            if(lj1.ch[i]&&lj2.ch[i]&&vis[lj1.ch[i]][lj2.ch[i]]!=flag) {
                q.push(make_pair(make_pair(lj1.ch[i],lj2.ch[i]),u.second+1));   
                vis[lj1.ch[i]][lj2.ch[i]]=flag;
            }
        }
    }
    puts("-1");
}
int main() {
    scanf("%s%s",a.s,b.s);
    n=strlen(a.s),m=strlen(b.s);
    for(int i=0;i<n;++i) add(a.s[i]-'a',0);
    for(int i=0;i<m;++i) add(b.s[i]-'a',1);
    //build a
    for(int i=0;i<n;++i)
        if(!dian[2][1].ch[a.s[i]-'a'])
            dian[2][1].ch[a.s[i]-'a']=i+2;
    for(int i=0;i<n;++i)
        for(int j=i+1;j<n;++j)
            if(!dian[2][i+2].ch[a.s[j]-'a'])
                dian[2][i+2].ch[a.s[j]-'a']=j+2;
    //build b
    for(int i=0;i<m;++i)
        if(!dian[3][1].ch[b.s[i]-'a'])
            dian[3][1].ch[b.s[i]-'a']=i+2;
    for(int i=0;i<m;++i)
        for(int j=i+1;j<m;++j)
            if(!dian[3][i+2].ch[b.s[j]-'a'])
                dian[3][i+2].ch[b.s[j]-'a']=j+2;
    flag++,bfs(0,1);
    flag++,bfs(0,3);
    flag++,bfs(2,1);
    flag++,bfs(2,3);
    return 0;
}

标签:dian,luoguP4112,SAM,int,BFS,pair,序列,自动机,first
来源: https://www.cnblogs.com/dsrdsr/p/11183186.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有