Title Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19845
The main idea: there is an underground mine, there are n tunnels connected, any of the two connection points between the only one tunnel connected. In order to reduce the miners ' danger, it is now decided to build some escape devices at the junction point, so that no matter which connection point collapses, all miners not at this junction can escape. Ask for a minimum installation of the escape device and its installation plan.
analysis of the problem, this is to find a dual-link component, we just have a cut point of the Point Dual Unicom components to install an escape device can be. The number of installed scenarios is the number of nodes in the point double Unicom minus 1, and when there is only one point of dual-link components only need to install two escape devices, program number is v* (V-1)/2;
#include <stdio.h> #include <string.h> #include <vector> #include <stack> #include < algorithm>using namespace Std;const int maxn = 100000 + 10;struct edge{int u, v; Edge (int i, int j): U (i), V (j) {}};vector<int> G[maxn], Bcc[maxn];int LOW[MAXN], DFN[MAXN], Bccno[maxn];bool iscut[ Maxn];int cur, cnt;stack<edge> S; On the edge, you don't have to deal with the cut point can exist in different connected components at the same time void Dfs (int u, int fa) {Dfn[u] = low[u] = ++cur; int child = 0; for (int i = 0; i < g[u].size (); i++) {int v = g[u][i]; if (v = = FA) continue; if (!dfn[v]) {S.push (Edge (U, v)); child++; DFS (v, u); Low[u] = min (Low[u], low[v]); if (Dfn[u] <= low[v])//u descendants of the earliest appearance of time is not less than the time you appear, you can be cut point {++cnt; Iscut[u] = true; Bcc[cnt].clear (); while (! S.empty ()) {Edge x = S.top (); S.pop (); if (bccno[x.u]! = CNT) {bcc[cnt].push_back (X.U); BCCNO[X.U] = cnt; } if (BCCNO[X.V]! = CNT) {bcc[cnt].push_back (X.V); BCCNO[X.V] = cnt; } if (X.u==u && x.v==v) break; }}} else if (Dfn[v] < Dfn[u])//about this judgment why not with the strong unicom and the same side of the double unicom bccno[v]==0 judgment, please pass by Daniel See to explain {S.push (Edge (U, v)); Low[u] = min (Low[u], dfn[v]); }} if (Fa<0 && child==1)//At the beginning of only child nodes, the starting point is not cut point iscut[u] = false;} void find_bcc (int n) {cur = cnt = 0; memset (DFN, 0, sizeof (DFN)); Memset (Iscut, False, sizeof (iscut)); memset (bccno, 0, sizeof (BCCNO)); DFS (1,-1);} int main () {int n, a, B, t = 0; int m = 0; while (scanf ("%d", &n), N) {for (int i = 0; I <= M i++) g[i].clear (); for (int i = 0; i < n; i++) {scanf ("%d%d", &a, &b); m = max (M, Max (A, b)); G[a].push_back (b); G[b].push_back (a); } FIND_BCC (n); Long Long ans1 = 0, ans2 = 1; for (int i = 1; I <= cnt; i++) {int cnt_cut = 0; for (int j = 0; J < Bcc[i].size (); j + +) {int k = bcc[i][j]; if (iscut[k]) cnt_cut++; } if (cnt_cut = = 1) {ans1++; Ans2 *= (Long Long) (Bcc[i].size ()-cnt_cut); }} if (cnt = = 1) {ans1 = 2; Ans2 = Bcc[cnt].size () * (Bcc[cnt].size ()-1)/2; } printf ("Case%d:%lld%lld\n", ++t, Ans1, ANS2); } return 0;}
Mining Your Own Business (Point double unicom)