The main topic: to give an image, if you want to make every two points between two different paths can reach each other, ask at least to add a few sides
How to solve the problem: the number of edges added is (1 points + 1)/2, which is the tree (leaf node +1)/2 after all connected components are shrunk
This is similar to what has been done before, here is just another way to move someone else's wording
If they belong to the same connected component, then their lowlink is the same, so they can be used to directly judge, and no need to re-DFS to each point to belong to the connected component
#include <cstdio>#include <cstring>#define N 5010#define M 100010#define min (a) (a) < (b)? (a): (b))structedge{int from, to, next;} E[M];BOOLRepeat[n][n], vis[m];intPre[n], Lowlink[n], Head[n],inch[N];intN, M, tot, Dfs_clock;voidAddedge (intUintV) {E[tot]. from= u; E[tot].to = v; E[tot].next = Head[u]; Head[u] = tot++;}voidInit () {scanf ("%d%d", &n, &m); Memset (Head,-1,sizeof(head)); tot =0;intU, v; for(inti =0; I < m; i++) {scanf ("%d%d", &u, &v);if(Repeat[u][v] | | repeat[v][u])Continue; REPEAT[U][V] = Repeat[v][u] =true; Addedge (U, v); Addedge (V, u); }}voidDfsintUintFA) {Lowlink[u] = pre[u] = ++dfs_clock; for(inti = Head[u]; I! =-1; i = e[i].next) {intv = e[i].to;if(Vis[i])Continue; Vis[i] = vis[i ^1] =true;if(!pre[v]) {DFS (V, u); Lowlink[u] = min (Lowlink[u], lowlink[v]); }Else if(v! = FA) {Lowlink[u] = min (Lowlink[u], pre[v]); } }}voidSolve () {Dfs_clock =0; Dfs1,0);intU, v; for(inti =0; i < tot; i++) {u = lowlink[e[i]. from]; v = lowlink[e[i].to];if(U! = V)inch[v]++; }intAns =0; for(inti =1; I <= N; i++)if(inch[I] = =1) ans++; printf"%d\n", (ans +1) /2);}intMain () {init (); Solve ();return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
POJ-3177 redundant Paths (strong connected component)