Redundant Paths
Time Limit: 1000MS |
|
Memory Limit: 65536K |
|
|
|
Description
In order to get from one of the F (1 <= f <= 5,000) grazing fields (which is numbered 1..F) to another field, Bessi E and the rest of the herd is forced to cross near the Tree of rotten Apples. The cows is now tired of often being forced to take a particular path and want to build some new paths so that they would Always has a choice of at least, separate routes between any pair of fields. They currently has at least one route between each pair of fields and want to has at least. Of course, they can only travel on official Paths when they move from one field to another.
Given a description of the current set of R (F-1 <= R <=) paths This each connect exactly both different field s, determine the minimum number of new paths (each of the which connects exactly.) that must is built so that there is at least, separate routes between any pair of fields. Routes is considered separate if they use none of the same paths, even if they visit the same intermediate field along th e-To.
There might already be more than one paths between the same pair of fields, and your may also build a new path that connect s the same fields as some and other path.
Input
Line 1:two space-separated integers:f and R
Lines 2..r+1:each line contains, space-separated integers which is the fields at the endpoints of some path.
Output
Line 1: A single integer which is the number of the new paths this must be built.
Sample Input
7 71 22 33 42 54 55 65 7
Sample Output
2
Hint
Explanation of the sample:
One visualization of the paths is:
1 2 3 +---+---+ | | | | 6 +---+---+ 4 /5 / / 7 +
Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.
1 2 3 +---+---+ : | | : | | 6 +---+---+ 4 /5 : / : /
Check Some of the routes:
1–2:1–> 2 and 1–> 6–> 5–> 2
1–4:1–> 2–> 3–> 4 and 1–> 6–> 5–> 4
3–7:3–> 4–> 7 and 3–> 2–> 5–> 7
Every pair of fields are, in fact, connected by and routes.
It's possible that adding some other path would also solve the problem (like one from 6 to 7). Adding paths, however, is the minimum.————————————————————————————————————————————————————————————————————————————————————————————————Test instructions: Give an undirected graph, guarantee is connected, ask to turn this undirected graph into a side double connected graph need to construct at least several new road. idea: First how to find out the side of the two connected components? The method is much simpler than the point-and-connect component:the first one is to find the bridge in the diagram, and then dye it with the Flood_fill method to ensure that the DFS does not pass through the bridge.
"A connected graph with a bridge, how to turn it through the plus edge into Edge Double Connected graph ? The method is to first find all the bridges and then delete the bridge edges, and each of the remaining connected blocks is a double-connected sub-graph. Each double-connected sub-graph is shrunk to a vertex, and then the bridge is added back, the last figure must be a tree, the edge connectivity is 1.
The number of nodes in the tree is 1, that is , the number of leaf nodes, which is recorded as Leaf. At least (leaf+1)/2 edges are added to the tree to allow the tree to connect to the edge, so at least the number of edges added is (leaf+1)/2. The method is to first connect an edge between the two nearest common ancestor's two leaf nodes, so that the two points can be shrunk to the path of the ancestors, because a formed ring must be double connected. Then find the two nearest public ancestor the furthest two leaf nodes, so that a pair to find out, happens to be (leaf+1)/2 times, all the points are shrunk together. "--byvoid
then the indent counts the degrees of each new point:Save the input edges, remove the two-point bcc_id, and if the same, the same connected component. otherwise statistical degrees. This is the idea of shrinking: Replace dots with color (ID). Attention!!! There is a lot of code on the web that is not correct, especially through the "same low value" of what kind of writing:"... The code does have a problem, because the low values of the points in the same two-connected component are not necessarily equal, so using the low value to determine if there is a problem in the same component is obvious. So our safest practice when in the Tarjan process, the bridge is marked out, and then use DFS to run every connected component ... "--Bright-thinking
p.s. Online can find a lot of code not to judge the re-edge, I think it is because the test data there is no heavy edge, but it may be because of the shrinking point, not very clear. Anyway to judge the heavy edge is not troublesome, plus is also 0msAC. The code is as follows:
/* * ID:J.SURE.1 * PROG: * lang:c++ */#include <cstdio> #include <cstdlib> #include <cstring> #include &l t;algorithm> #include <ctime> #include <cmath> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <string> #include <climits> #include < Iostream> #define MEM (f, X) memset (f, X, sizeof (f)) #define PB push_back#define LL long longusing namespace Std;const int INF = 0x3f3f3f3f;const double eps = 1e-8;/****************************************/const int N = 5e3+5, M = 2e4+5;struct Edge {int V, next, IDX, tag; Edge () {} edge (int _v, int _next, int _idx, int _tag = 0): V (_v), Next (_next), IDX (_IDX), tag (_tag) {}}e[m];int n, M, deep, tot, Bcc_cnt;int dfn[n], head[n], bcc_id[n], line[n][2], Deg[n];bool isbri[m];void __init__ () {bcc_cnt = tot = Deep = 0; for (int i = 0; i < n; i++) {Head[i] =-1; Deg[i] = Dfn[i] = Bcc_id[i] = 0; } Mem (Isbri, 0);} void Add (int u, int v, int idx) {int p; for (p = head[u]; ~p; p = e[p].next) {if (e[p].v = = v) {e[p].tag++; return; }} E[tot] = Edge (V, Head[u], IDX); Head[u] = tot++;} int dfs (int u, int fa) {int Lowu = dfn[u] = ++deep; for (int i = head[u]; ~i; i = e[i].next) {int v = E[I].V; if (!dfn[v]) {int LOWV = DFS (v, u); Lowu = min (Lowu, LOWV); if (Lowv > Dfn[u] &&!e[i].tag) isbri[e[i].idx] = 1; } else if (Dfn[v] < Dfn[u] && v! = FA) Lowu = min (Lowu, dfn[v]); } return LOWU;} void flood (int u) {bcc_id[u] = bcc_cnt; for (int i = head[u]; ~i; i = e[i].next) {if (Isbri[e[i].idx]) continue; int v = E[I].V; if (!bcc_id[v]) {flood (v); }}}int Main () {#ifdef j_sure freopen ("000.in", "R", stdin); Freopen ("999.out", "w", stdout), #endif while (~scanf ("%d%d", &n, &m)){int ID = 0; __init__ (); for (int i = 0; i < m; i++) {int u, v; scanf ("%d%d", &u, &v); u--; v--; Line[i][0] = u; Line[i][1] = v; Add (U, V, ID); Add (V, U, id++); } DFS (0,-1); for (int i = 0; i < n; i++) {if (!bcc_id[i]) {bcc_cnt++; Flood (i); }} for (int i = 0; i < m; i++) {int u = bcc_id[line[i][0]] [v = bcc_id[line[i][1]]; if (U = v) {deg[u]++; deg[v]++; }} int ans = 0; for (int i = 1; I <= bcc_cnt; i++) {if (deg[i] = = 1) ans++; } printf ("%d\n", (ans+1)/2); } return 0;}
"Connect Graph | Edge Double connect + indent" POJ-3177 redundant Paths