[P2444 POI2000] 病毒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
问题等价于在字典图中找一个环,这个环要满足环上节点不是所有所给字符串最后一个字符结尾的点。
找环算法:
void dfs(int u) {in[u] = 1; // u在当前dfs路径中for(auto y: g[u]) {if(in[y]) {// 与dfs路径中点重合,成环fg = 1;}// 如果之前已经访问过y点,表示经过y点不会有环if(vis[y]) continue; vis[y] = 1;dfs(y);}in[u] = 0;
}
本题找环,还需要保证,y点不是所给字符串中最后一个字符结尾的点。
代码:
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <random>
#include <sstream>
#include <numeric>
#include <stdio.h>
#include <functional>
#include <bitset>
#include <algorithm>
using namespace std;// #define Multiple_groups_of_examples
// #define int_to_long_long
#define IOS std::cout.tie(0);std::cin.tie(0)->sync_with_stdio(false); // 开IOS,需要保证只使用Cpp io流 *
#define dbgnb(a) std::cout << #a << " = " << a << '\n';
#define dbgtt cout<<" !!!test!!! "<<'\n';
#define rep(i,x,n) for(int i = x; i <= n; i++)#define all(x) (x).begin(),(x).end()
#define pb push_back
#define vf first
#define vs secondtypedef long long LL;
#ifdef int_to_long_long
#define int long long
#endif
typedef pair<int,int> PII;const int INF = 0x3f3f3f3f;
const int N = 2e5 + 21;namespace golitter {
namespace ACAM {
// https://www.luogu.com.cn/problem/P5357
// https://zhuanlan.zhihu.com/p/546999184
struct acam {static const int M = 300005;struct node {int fail;int ch[28] = {0};}tr[M];int cnt = 0;map<int,int> ref;vector<int> g[M];int ans[M];bitset<M> in, vis, isend;void insert(string &s, int id) {int u = 0;for(auto c: s) {int last = c == '_' ? 26 : c - 'a';if(!tr[u].ch[last]) {tr[u].ch[last] = ++cnt;}u = tr[u].ch[last];}isend[u] = 1;ref[id] = u;}void build() {queue<int> que;for(int i = 0; i < 27; ++i) {if(tr[0].ch[i]) que.push(tr[0].ch[i]);}while(que.size()) {int u = que.front(); que.pop();for(int i = 0; i < 27; ++i) {if(tr[u].ch[i]) {tr[tr[u].ch[i]].fail = tr[tr[u].fail].ch[i];que.push(tr[u].ch[i]);if(isend[tr[tr[u].ch[i]].fail]) isend[tr[u].ch[i]] = 1;} else tr[u].ch[i] = tr[tr[u].fail].ch[i];}}for(int i = 1; i <= cnt; ++i) g[tr[i].fail].push_back(i);}void query(string &S) {int u = 0;for(auto c: S) {int last = c == '_' ? 26 : c - 'a';u = tr[u].ch[last];ans[u]++;}}bool fg = 0;bool check() {dfs(0);return fg;}void dfs(int u) {in[u] = 1;for(int i = 0; i <= 1; ++i) {if(in[tr[u].ch[i]]) {fg = 1;return ;}if(vis[tr[u].ch[i]] || isend[tr[u].ch[i]]) continue;vis[tr[u].ch[i]] = 1;dfs(tr[u].ch[i]);}in[u] = 0;}void clear() {for(int i = 0; i < M; ++i) {tr[i] = {};g[i].clear();ans[i] = 0;}ref.clear();cnt = 0;}
}trie;}}
using golitter::ACAM::trie;
void inpfile();
void solve() {int n; cin>>n;for(int i = 0; i< n; ++i) {string s; cin>>s;for(auto&t: s) {if(t == '1') t = 'b';else t = 'a';}trie.insert(s, i);}trie.build();puts(trie.check() ? "TAK" : "NIE");
}
#ifdef int_to_long_long
signed main()
#else
int main()
#endif{#ifdef Multiple_groups_of_examplesint T; cin>>T;while(T--)#endifsolve();return 0;
}
void inpfile() {#define mytest#ifdef mytestfreopen("ANSWER.txt", "w",stdout);#endif
}