AC自动机,Tarjan(ZOJ 3784,String of Infinity)
2017-04-26 18:26
253 查看
#include<bits/stdc++.h> using namespace std; const int maxn = 100010; const int maxc = 26; int MAXC; int ch[maxn][maxc]; int val[maxn]; int sz; int f[maxn]; vector<int>SET[maxn]; int pre[maxn]; int low[maxn]; int scc[maxn]; int dfs_clc; int scc_cnt; stack<int>s; int vis[maxn]; struct Trie { void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); val[0]=0; char s[5]; s[1]='\0'; for(int c=0;c<MAXC;c++) { s[0]='a'+c; insert(s); val[sz-1]=0; } } int idx(char c) { return c-'a'; } void insert(char* s) { int l=strlen(s); int u=0; for(int i=0;i<l;i++) { int v=idx(s[i]); if(!ch[u][v]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][v]=sz++; } u=ch[u][v]; } val[u]=1; } void getfail() { queue<int>q; f[0]=0; for(int c=0;c<MAXC;c++) { f[ch[0][c]]=0; q.push(ch[0][c]); } while(!q.empty()) { int r=q.front(); q.pop(); for(int c=0;c<MAXC;c++) { int u=ch[r][c]; if(!u) { ch[r][c]=ch[f[r]][c]; continue; } if(val[u]) continue; int v=f[r]; while(v&&val[ch[v][c]]) v=f[v]; f[u]=ch[v][c]; val[u]|=val[f[u]]; if(!val[u]) q.push(u); } } } void dfs(int u) { pre[u]=low[u]=++dfs_clc; s.push(u); for(int c=0;c<MAXC;c++) if(!val[ch[u][c]]) { int v=ch[u][c]; if(!pre[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if(!scc[v]) low[u]=min(low[u],pre[v]); } if(pre[u]==low[u]) { scc_cnt++; while(1) { int x=s.top(); s.pop(); scc[x]=scc_cnt; SET[scc_cnt].push_back(x); if(x==u) break; } } } void handle() { for(int i=0;i<=sz;i++) { SET[i].clear(); pre[i]=0; low[i]=0; scc[i]=0; } dfs_clc=0; scc_cnt=0; while(!s.empty()) s.pop(); dfs(0); } int DFS(int u) { vis[u]=1; int ret=0; for(int c=0;c<MAXC;c++) if(scc[u]==scc[ch[u][c]]) { int v=ch[u][c]; if(vis[v]) ret++; if(!vis[v]) ret+=DFS(v); } return ret; } bool ok() { for(int i=0;i<=sz;i++) vis[i]=0; handle(); for(int i=1;i<=scc_cnt;i++) if(DFS(SET[i][0])>1) return true; return false; } }trie; char str[1010]; void solve() { int N; scanf("%d %d",&N,&MAXC); trie.init(); while(N--) { scanf("%s",str); trie.insert(str); } trie.getfail(); if(trie.ok()) puts("Yes"); else puts("No"); } int main() { int T; scanf("%d",&T); while(T--) solve(); return 0; }
相关文章推荐
- zoj 3784 String of Infinity(难题,方法妙)
- ZOJ3784 String of Infinity 高大上的AC自动机 数据原来这么水啊!不算输入输出只有5-7行
- [AC自动机] zoj Searching the String
- zoj 3228 Searching the String 【AC自动机】
- ZOJ 3985 String of CCPC (字符串判断)
- zoj 3228 Searching the String【ac自动机】
- zoj -- 3228 Searching the String(AC自动机)
- ZOJ 3985 String of CCPC
- ZOJ - 3985 - String of CCPC (分类讨论)
- ZOJ1979 POJ2553 The Bottom of a Graph,经典Tarjan
- ZOJ 3985 && 2017CCPC秦皇岛 E:String of CCPC
- ZOJ 题目3228 Searching the String(AC自动机,子川匹配个数)
- zoj3784 String of Infinity 思维。。。
- zoj&CCPC秦皇岛站E-思维-String of CCPC
- ZOJ 3985 String Of CCPC 字符串,模拟
- ZOJ3784 String of Infinity(AC自动机&&强连通分量)
- poj 2553 zoj 1979 The Bottom of a Graph(强联通分量 Tarjan)
- ZOJ - 3985 String of CCPC (2017CCPC秦皇岛站 简单题)
- Reverse Vowels of a String
- ZOJ 2771 Get Out of the Glass(DP)