zoukankan      html  css  js  c++  java
  • bzoj1195 [HNOI2006]最短母串 AC 自动机+状压+bfs

    题目传送门

    https://lydsy.com/JudgeOnline/problem.php?id=1195

    题解

    建立 AC 自动机,然后构建出 trie 图。

    然后直接在 trie 图上走。但是我们需要经过每一个串。

    所以我们处理一下每个点代表了哪些串,然后把状态加入进 bfs 状态。

    然后 bfs 就可以了。


    (O(n))

    #include<bits/stdc++.h>
    
    #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
    #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define fi first
    #define se second
    #define pb push_back
    
    template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
    template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
    
    typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
    
    template<typename I> inline void read(I &x) {
    	int f = 0, c;
    	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    	x = c & 15;
    	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    	f ? x = -x : 0;
    }
    
    const int N = 12 + 1;
    const int M = 50 + 1;
    const int NM = 12 * 50 + 1;
    const int NP = (1 << 12);
    const int NMP = 12 * 50 * ((1 << 12) - 1) + 1;
    
    int n, m, nod;
    int q[NMP], q2[NMP], fr[NM][NP];
    char s[N], ans[NM];
    struct Node { int c[26], fa, v; char s; } t[NM];
    
    inline void ins(char *s, int id) {
    	int n = strlen(s + 1), o = 0;
    	for (int i = 1; i <= n; ++i) {
    		if (!t[o].c[s[i] - 'A']) t[o].c[s[i] - 'A'] = ++nod, t[nod].s = s[i];
    		o = t[o].c[s[i] - 'A'];
    	}
    	t[o].v |= 1 << (id - 1);
    }
    inline void build() {
    	int hd = 0, tl = 0;
    	for (int i = 0; i < 26; ++i) if (t[0].c[i]) q[++tl] = t[0].c[i];
    	while (hd < tl) {
    		int x = q[++hd]; t[x].v |= t[t[x].fa].v;
    		for (int i = 0; i < 26; ++i)
    			if (t[x].c[i]) t[t[x].c[i]].fa = t[t[x].fa].c[i], q[++tl] = t[x].c[i];
    			else t[x].c[i] = t[t[x].fa].c[i];
    	}
    }
    
    inline void work() {
    	int hd = 0, tl = 1, S = (1 << n) - 1;
    	q[tl] = 0, q2[tl] = 0, fr[0][0] = -1;
    	while (hd < tl) {
    		int x = q[++hd];
    		int s = q2[hd];
    //		dbg("x = %d, s = %d
    ", x, s);
    		for (int i = 0; i < 26; ++i) if (t[x].c[i]) {
    			int y = t[x].c[i], ss = s | t[y].v;
    //			dbg("y = %d, ss = %d
    ", y, ss);
    			if (!fr[y][ss]) {
    				fr[y][ss] = hd, q[++tl] = y, q2[tl] = ss;
    //				dbg("****** y = %d, ss = %d
    ", y, ss);
    				if (ss == S) {
    					int len = 0, z = y, zs = ss, zz;
    					while (~fr[z][zs]) ans[++len] = t[z].s, zz = fr[z][zs], z = q[zz], zs = q2[zz];
    					while (len) putchar(ans[len--]);
    					puts("");
    //					dbg("*********
    ");
    					return;
    				}
    				assert(fr[y][ss]);
    			}
    		}
    	}
    }
    
    inline void init() {
    	read(n);
    	for (int i = 1; i <= n; ++i) scanf("%s", s + 1), ins(s, i);
    	build();
    //	dbg("*************
    ");
    }
    
    int main() {
    #ifdef hzhkk
    	freopen("hkk.in", "r", stdin);
    #endif
    	init();
    	work();
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    SQL Server Audit监控触发器状态
    SQL Server 数据变更时间戳(timestamp)在复制中的运用
    SQL Server 更改跟踪(Chang Tracking)监控表数据
    SQL Server 变更数据捕获(CDC)监控表数据
    SQL Server 事件通知(Event notifications)
    SQL Server 堆表行存储大小(Record Size)
    SQL Server DDL触发器运用
    SQL Server 默认跟踪(Default Trace)
    SQL Server 创建数据库邮件
    SQL Server 跨网段(跨机房)FTP复制
  • 原文地址:https://www.cnblogs.com/hankeke/p/bzoj1195.html
Copyright © 2011-2022 走看看