The complete code is given in the Rujia book.
Here's the idea:
There must be one or more double connected components known by test instructions;
Suppose a double-connected component has a cut-top. The Taiping well must not be hit on the top of the cut.
Instead, choose a random point beyond the top of the cut;
Assuming that there is no cut-off, a two well is to be struck on the double connected component
As for the drilling scheme. See Code
#include <cstdio> #include <cstring> #include <vector> #include <stack> #include <map> using namespace Std; const int N = 50005; struct Edge {int u, v; Edge () {} edge (int u, int v) {this->u = u; This->v = v; } }; int pre[n], bccno[n], Dfs_clock, bcc_cnt; BOOL Iscut[n]; Vector<int> G[n], bcc[n]; Stack<edge> S; int dfs_bcc (int u, int fa) {int Lowu = pre[u] = ++dfs_clock; int child = 0; for (int i = 0; i < g[u].size (); i++) {int v = g[u][i]; Edge e = Edge (U, v); if (!pre[v]) {S.push (e); child++; int LOWV = DFS_BCC (V, u); Lowu = min (Lowu, LOWV); if (LOWV >= pre[u]) {Iscut[u] = true; bcc_cnt++; Bcc[bcc_cnt].clear (); Start from 1 while (1) {Edge x = S.top (); S.pop (); if (BCCNO[X.U]! = bcc_cnt) {bcc[bcc_cnt].push_back (X.U); bccno[x.u] = bcc_cnt;} if (BCCNO[X.V]! = bcc_cnt) {bcc[bcc_cnt].push_back (X.V); bccno[x.v] = bcc_cnt;} if (x.u = = U && x.v = = v) break; }}}} else if (Pre[v] < Pre[u] && v! = FA) {s.push (e); Lowu = min (Lowu, pre[v]); }} if (FA < 0 && child = = 1) Iscut[u] = false; return LOWU; } int St; void Find_bcc () {memset (pre, 0, sizeof (pre)); memset (iscut, 0, sizeof (iscut)); memset (bccno, 0, sizeof (BCCNO)); Dfs_clock = bcc_cnt = 0; DFS_BCC (0,-1); } int n, m; typedef long Long LL; void Solve () {ll ans1 = 0, ans2 = 1; for (int i = 1; I <= bcc_cnt; i++) {int cut_cnt = 0; for (int j = 0; J < Bcc[i].size (); j + +) if (Iscut[bcc[i][j]]) cut_cnt++; if (cut_cnt = = 1) {ans1++; Ans2 *= (LL) (Bcc[i].size ()-cut_cnt); }} if (bcc_cnt = = 1) {ans1 = 2; Ans2 = (ll) bcc[1].size () * (Bcc[1].size ()-1)/2; } printf ("%lld%lld\n", ans1, ANS2); } int main () {int cas = 0; while (~SCANF ("%d", &m) && m) {int u, V, Max = 0; while (m--) {scanf ("%d%d", &u, &v); u--; v--; G[u].push_back (v); G[v].push_back (U); max = max (max, u); max = max (max, v); } find_bcc (); printf ("Case%d:", ++cas); Solve (); for (int i = 0; I <= Max; i++) g[i].clear (); } return 0; }
UVA 1108-mining Your Own Business