P2444 [POI2000]病毒
ps:注意一点,如果一个节点的fail指针指向的是危险节点,那么这个节点也是危险节点。
const int N = 30005; struct node { int fail, Count, vis[2]; node () { fail = Count = 0; vis[0] = vis[1] = 0; } }; struct AcAutomation { int cnt; node a[N]; bool use[N], pa[N]; void Inite() { cnt = 0; mem(pa, 0); mem(use, 0); } void Build(char *s) { int n = strlen(s); int now = 0; rep(i, 0, n) { int id = s[i] - '0'; if (!a[now].vis[id]) a[now].vis[id] = ++cnt; now = a[now].vis[id]; } a[now].Count++; } void getFail() { queue<int> q; rep(i, 0, 2) if (a[0].vis[i]) { a[a[0].vis[i]].fail = 0; q.push(a[0].vis[i]); } while(!q.empty()) { int now = q.front(); q.pop(); rep(i, 0, 2) { if (a[now].vis[i]) { a[a[now].vis[i]].fail = a[a[now].fail].vis[i]; q.push(a[now].vis[i]); if (a[a[a[now].fail].vis[i]].Count) a[a[now].vis[i]].Count++; } else { a[now].vis[i] = a[a[now].fail].vis[i]; } } } } bool DFS(int now = 0) { use[now] = 1; rep(i, 0, 2) { if (use[a[now].vis[i]]) { puts("TAK"); exit(0); } else if (!a[a[now].vis[i]].Count) { //pa[a[now].vis[i]] = 1; DFS(a[now].vis[i]); } } use[now] = 0; } }; int n; char s[N]; AcAutomation Ac; int main() { sc(n); Ac.Inite(); rep(i, 0, n) { scanf("%s", s); Ac.Build(s); } Ac.getFail(); Ac.DFS(); puts("NIE"); return 0; }