Codeforces 104C Cthulhu dfs violence | dual-connection deflation, codeforces104c
Question link: Click the open link
Question:
Undirected graph with m edge given n points
Ask if there is only one simple ring and some trees in the figure, and the root of these trees is on this simple ring.
Blind write a dot pair .. =
# Include <stdio. h> # include <iostream> # include <algorithm> # include <string. h> # include <queue> # include <vector> # include <set> using namespace std; # define N 105 # define M 100005 # define inf 10000000 struct Edge {int from, to, next;} edge [2 * M]; int head [N], edgenum; int Low [N], DFN [N], Stack [N]; // The value of the Belong array is 1 ~ Blockint Index, top; int Belong [N], block; // The connected block number of the New Graph (1 ~ Block) bool Instack [N]; int bridge; // Number of cut bridges vector <int> bcc [N]; void addedge (int u, int v) {Edge E = {u, v, head [u]}; edge [edgenum] = E; head [u] = edgenum ++; Edge E2 = {v, u, head [v]}; edge [edgenum] = E2; head [v] = edgenum ++;} void Tarjan (int u, int pre) {int v; low [u] = DFN [u] = ++ Index; Stack [top ++] = u; Instack [u] = true; for (int I = head [u]; ~ I; I = edge [I]. next) {v = edge [I]. to; // if the duplicate edge is valid, change the following sentence to: if (v = pre & pre_num = 0) {pre_num ++; continue ;} pre_num defines int pre_num = 0; if (v = pre) continue; if (! DFN [v]) {Tarjan (v, u); if (Low [u]> Low [v]) Low [u] = Low [v]; if (Low [v]> Low [u]) bridge ++;} else if (Instack [v] & Low [u]> DFN [v]) low [u] = DFN [v];} if (Low [u] = DFN [u]) {block ++; bcc [block]. clear (); do {v = Stack [-- top]; Instack [v] = false; Belong [v] = block; bcc [block]. push_back (v);} while (v! = U) ;}} void work (int l, int r) {memset (DFN, 0, sizeof (DFN); memset (Instack, false, sizeof (Instack )); index = top = block = bridge = 0; for (int I = l; I <= r; I ++) if (! DFN [I]) Tarjan (I, I) ;}vector <int> G [N]; void suodian () {for (int I = 1; I <= block; I ++) G [I]. clear (); for (int I = 0; I <edgenum; I ++ = 2) {int u = Belong [edge [I]. from], v = Belong [edge [I]. to]; if (u = v) continue; G [u]. push_back (v), G [v]. push_back (u) ;}} void init () {edgenum = 0; memset (head,-1, sizeof (head);} int n, m, vis [N], siz [N], f [N]; int find (int x) {return x = f [x]? X: f [x] = find (f [x]);} void Union (int x, int y) {int fx = find (x ), fy = find (y); if (fx = fy) return; if (fx> fy) swap (fx, fy); f [fx] = fy ;} bool dfs (int u) {vis [u] = 1; bool OK = true; for (int I = 0; I <G [u]. size (); I ++) {int v = G [u] [I]; if (vis [v]) continue; if (bcc [v]. size ()> 1) OK = false; if (dfs (v) = false) OK = false;} return OK;} set <int> myset; bool solve () {int I, u, v; init (); for (I = 1; I <= n; I ++) f [I] = I; while (m --) {Scanf ("% d", & u, & v); addedge (u, v); Union (u, v);} myset. clear (); for (I = 1; I <= n; I ++) myset. insert (find (I); if (myset. size ()> 1) return false; work (1, n); suodian (); memset (vis, 0, sizeof vis); memset (siz, 0, sizeof siz ); for (I = 0; I <edgenum; I + = 2) siz [u] + = (Belong [edge [I]. from] = Belong [edge [I]. to]); for (I = 1; I <= block; I ++) if (! Vis [I] & bcc [I]. size ()> 1 & bcc [I]. size () = siz [I] & G [I]. size ()> = 3) if (dfs (I) return true; return false;} int main () {while (~ Scanf ("% d", & n, & m) solve ()? Puts ("FHTAGN! "): Puts (" NO "); return 0;}/* 6 61 22 33 14 55 66 4 */