[BZOJ2938][Poi2000]病毒(AC自动机+拓扑排序)
2016-12-24 23:18
288 查看
题目描述
传送门题解
如果把给出的所有串建成trie树的话,那么有解的条件就是在匹配不到end节点的情况下无限地匹配下去。注意不是只有每一个串的结束节点才是end节点,根据fail树的性质,假设y的fail指针指向x,那么如果x有end标记y也一定有end标记,因为x是y的一个后缀。
对于某一个节点如果它没有某一个儿子那么就把它这个儿子表示成它的fail的那个儿子。这样的话就形成了一个trie图。无限匹配的条件就是在不走有标记的节点的情况下图中有环。
那么有向图找环用拓扑排序即可以解决。
代码
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; #define N 30005 char s ; int n,sz; int ch [2],fail ; queue <int> q; bool is_end ,vis ; int tot,point ,nxt[N*2],v[N*2],in ; void insert() { int len=strlen(s),now=0; for (int i=0;i<len;++i) { int x=s[i]-'0'; if (!ch[now][x]) ch[now][x]=++sz; now=ch[now][x]; } is_end[now]=1; } void make_fail() { while (!q.empty()) q.pop(); for (int i=0;i<=1;++i) if (ch[0][i]) q.push(ch[0][i]); while (!q.empty()) { int now=q.front();q.pop(); for (int i=0;i<=1;++i) { if (!ch[now][i]) { ch[now][i]=ch[fail[now]][i]; continue; } fail[ch[now][i]]=ch[fail[now]][i]; if (is_end[fail[ch[now][i]]]) is_end[ch[now][i]]=1; q.push(ch[now][i]); } } } void add(int x,int y) { ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; } void dfs(int x) { vis[x]=true; for (int i=0;i<=1;++i) { add(x,ch[x][i]);++in[ch[x][i]]; if (!vis[ch[x][i]]&&!is_end[ch[x][i]]) dfs(ch[x][i]); } } bool topo() { int cnt=0; while (!q.empty()) q.pop(); for (int i=0;i<=sz;++i) if (!in[i]) q.push(i); while (!q.empty()) { int now=q.front();q.pop(); ++cnt; for (int i=point[now];i;i=nxt[i]) { --in[v[i]]; if (!in[v[i]]) q.push(v[i]); } } return cnt<sz; } int main() { scanf("%d\n",&n); for (int i=1;i<=n;++i) { gets(s); insert(); } make_fail(); dfs(0); if (topo()) puts("TAK"); else puts("NIE"); }
总结
转化的思想太重要了。。相关文章推荐
- BZOJ 2938 Poi2000 病毒 AC自动机+拓扑排序
- [bzoj2938] [Poi2000]病毒
- BZOJ 2938 [Poi2000]病毒
- [bzoj2938][Poi2000]病毒
- [BZOJ 2938][Poi2000]病毒
- BZOJ_2938_[Poi2000]病毒_AC自动机
- BZOJ 2938 [Poi2000]病毒
- bzoj2938 [Poi2000]病毒 ac自动机
- [BZOJ2938][POI2000]病毒 做题笔记
- [bzoj2938][Poi2000]病毒_AC自动机
- [BZOJ2938][POI2000]病毒(AC自动机+dfs)
- bzoj2938 [POI2000]病毒(ACAM+拓扑序判环)
- [bzoj2938][Poi2000]病毒 AC自动机
- BZOJ 2938 [Poi2000]病毒(AC自动机)
- bzoj2938 [Poi2000]病毒
- AC自动机【poi2000】bzoj2938 病毒
- 【bzoj2938】[Poi2000]病毒 AC自动机
- 【bzoj2938】[Poi2000]病毒 AC自动机
- 【BZOJ】【2938】【POI2000】病毒
- 【bzoj2938】[Poi2000]病毒