zoukankan      html  css  js  c++  java
  • [HNOI2006] 最短母串问题

    Description

    给定 (n le 12) 个字符串,要求找到一个最短的母串使得这 (n) 个字符串都是它的子串。如果有多个合法解则输出字典序最小的。每个字符串的长度不超过 (50)

    Solution

    (n) 个字符串建立 AC 自动机,对于每个串的末尾结点,打上标记。

    建自动机的时候记得把标记下传一下

    然后跑 BFS 即可,记录下每个点的来源,然后倒序输出

    BFS 的时候先从小边走,以保证字典序

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1005;
    
    int ch[N][26],fi[N],val[N],n,m,t1,t2,t3,t4,ind;
    pair<short,short> from[N][5005];
    char chr[N][5005],vis[N][5005];
    
    void ins(char *s,int px) {
    	int len=strlen(s),p=0;
    	for(int i=0;i<len;i++) {
    		if(ch[p][s[i]-'A']==0) ch[p][s[i]-'A']=++ind;
    		p=ch[p][s[i]-'A'];
    	}
    	val[p]|=1<<px;
    }
    
    void build() {
    	queue <int> q;
    	for(int i=0;i<26;i++) if(ch[0][i]) q.push(ch[0][i]);
    	while(!q.empty()) {
    		int p=q.front(); q.pop();
    		for(int i=0;i<26;i++)
    			if(ch[p][i]) fi[ch[p][i]]=ch[fi[p]][i],q.push(ch[p][i]),val[ch[p][i]]|=val[fi[ch[p][i]]];
    			else ch[p][i]=ch[fi[p]][i];
    	}
    }
    
    void printans(int p,int s) {
        if(p) {
            printans(from[p][s].first, from[p][s].second);
            cout<<chr[p][s];
        }
    }
    
    void bfs() {
        queue <pair<int,int> > q;
        q.push({0,0});
        vis[0][0]=1;
        while(q.size()) {
            pair<int,int> pr = q.front();
            q.pop();
            int p=pr.first, s=pr.second;
            for(int i=0;i<26;i++) {
                int p1=ch[p][i], s1=s|val[p1];
                if(!vis[p1][s1]) {
                    q.push({p1,s1});
                    from[p1][s1]={p,s};
                    chr[p1][s1]=i+'A';
                    vis[p1][s1]=1;
                    if(s1==(1<<n)-1) {
                        printans(p1,s1);
                        return;
                    }
                }
            }
        }
    }
    
    char str[N];
    
    int main() {
    	cin>>n;
    	for(int i=1;i<=n;i++) cin>>str,ins(str,i-1);
    	build();
    	bfs();
    }
    
    
  • 相关阅读:
    【动态规划】 EditDistance
    招聘
    算法01 C语言设计
    keras04
    电影《邪不压正》打动我的
    Eclipse
    6.面向对象编程(下)2
    获取一个1-100之间的随机数
    java如何使用帮助文档api
    3.java基础语法(下)
  • 原文地址:https://www.cnblogs.com/mollnn/p/13195275.html
Copyright © 2011-2022 走看看