From af0b89f5c80cfceb8d2fab5b06e4ed42f8a0c2ca Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Sun, 29 Jan 2023 10:20:11 +0800 Subject: [PATCH] G - Subgraph Isomorphism https://codeforces.com/gym/104090/submission/191043121 --- Gym/104090/G/G.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 Gym/104090/G/G.cpp diff --git a/Gym/104090/G/G.cpp b/Gym/104090/G/G.cpp new file mode 100644 index 00000000..c742fbbb --- /dev/null +++ b/Gym/104090/G/G.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include + +using std::cin; +using std::cout; +const char endl = '\n'; + +// 树哈希 +// https://peehs-moorhsum.blog.uoj.ac/blog/7891 + +unsigned long long h(unsigned long long x) { + return x * x * x * 1237123 + 19260817; +} + +unsigned long long f(unsigned long long x) { + return h(x & ((1ull << 31) - 1)) + h(x >> 31); +} + +int main() { + std::ios::sync_with_stdio(false); + cin.tie(nullptr); + + int t; + + cin >> t; + + while (t--) { + int n, m; + + cin >> n >> m; + + std::vector> g(n + 1); + + for (int i = 1, x, y; i <= m; i++) { + cin >> x >> y; + + g[x].emplace_back(y); + g[y].emplace_back(x); + } + + if (m > n) { + cout << "NO" << endl; + + continue; + } + + if (m < n) { + cout << "YES" << endl; + + continue; + } + + // assert(n == m); + + std::stack st; + std::vector circle; + std::vector vis1(n + 1); + + std::function dfs1 = [&](int u, int f) -> void { + if (vis1[u]) { + if (circle.empty()) { + while (!st.empty() && st.top() != u) { + circle.emplace_back(st.top()); + st.pop(); + } + + circle.emplace_back(u); + } + + return; + } + + vis1[u] = true; + st.emplace(u); + + for (int v : g[u]) { + if (v == f) continue; + + dfs1(v, u); + } + + if (!st.empty()) st.pop(); + }; + + dfs1(1, 0); + + std::vector vis2(n + 1); + std::vector hash(n + 1); + std::unordered_set set; + + for (int x : circle) vis2[x] = true; + + std::function dfs2 = [&](int u) -> void { + vis2[u] = true; + hash[u] = 1; + + for (int v : g[u]) { + if (vis2[v]) continue; + + dfs2(v); + + hash[u] += f(hash[v]); + } + }; + + for (int x : circle) { + dfs2(x); + set.emplace(hash[x]); + } + + bool flag = circle.size() % 2 == 0; + + for (int i = 0; i + 2 < circle.size(); i++) { + if (hash[circle[i]] != hash[circle[i + 2]]) { + flag = false; + + break; + } + } + + cout << (set.size() == 1 || flag ? "YES" : "NO") << endl; + } + + return 0; +}