LA3907 Puzzle

来源:互联网 发布:sql server 2000 mac 编辑:程序博客网 时间:2024/06/06 21:00

题意:给s个禁止子串,求不含他们的最长串。

思路:用这s个禁止串建一个 AC自动机,那么这些串的尾节点表示禁止节点。然后DFS判断是否存在环(为环就无限长了),在DFS的时候顺便记录下跑的路径,在输出字符串的时候就方便了。

代码:

#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;#define nn 100040bool loop;//判断环int road[nn];//记录路径int vis[nn], dp[nn];//dp[i]表示以i节点结尾的字符串的长度struct aho{int ch[nn][26];int last[nn], val[nn], f[nn];int sz;void init(){sz = 1;memset(ch[0], 0, sizeof(ch[0]));val[0] = 0;}int idx(char c){return c - 'A';}void insert(char* s, int m){int n = strlen(s), u = 0;for (int i = 0; i<n; i++){int c = idx(s[i]);if (!ch[u][c]){memset(ch[sz], 0, sizeof(ch[sz]));val[sz] = 0;ch[u][c] = sz++;}u = ch[u][c];}val[u] = 1;//标记所有不能走到的点}void get_f(int m){queue<int>q;f[0] = 0;for (int c = 0; c<m; c++){int u = ch[0][c];if (u){f[u] = 0;q.push(u);last[u] = 0;}}while (!q.empty()){int r = q.front(); q.pop();for (int c = 0; c<m; c++){int u = ch[r][c];if (!u){ch[r][c] = ch[f[r]][c];continue;}q.push(u);int v = f[r];while (v && !ch[v][c]) v = f[v];f[u] = ch[v][c];last[u] = val[f[u]] ? f[u] : last[f[u]];}}}int dfs(int now, int m){if (loop) return 0;if (dp[now] != -1) return dp[now];dp[now] = 0;for (int i = m - 1; i >= 0; i--){if (!val[ch[now][i]]){if (vis[ch[now][i]])//发现回路{loop = 1;return 0;}else{vis[ch[now][i]] = 1;if (dp[now]<1 + dfs(ch[now][i], m)){dp[now] = 1 + dp[ch[now][i]];road[now] = i; //记录路径,表示now节点选的下一个节点位置}vis[ch[now][i]] = 0;}}}return dp[now];}};aho t;char str[100];int main(){int T, n, m;scanf("%d", &T);while (T--){t.init();scanf("%d%d", &n, &m);for (int i = 0; i<m; i++){scanf("%s", str);t.insert(str, n);}t.get_f(n);loop = 0;memset(vis, 0, sizeof(vis));memset(dp, -1, sizeof(dp));vis[0] = 1;t.dfs(0, n);if (loop || !dp[0]) printf("No\n");else{int now = 0;for (int i = 0; i<dp[0]; i++){printf("%c", road[now] + 'A');now = t.ch[now][road[now]];}printf("\n");}}return 0;}

0 0
原创粉丝点击