Timestamp Dfs_clock: It's plain to note that the order in which each node is accessed is recorded. Suppose we use the pre to save, then if Pre[u] > Pre[v], then we can know the first to access the V, after access to U.
Now given an edge, (U, v), and the ancestor of U is FA, if there is pre[v] < Pre[u] && v! = FA, then (U, v) is a reverse edge.
1 to find the connected component:
A mutually accessible node is called a connected component;
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include < cstring> #include <stack> #include <vector> #include <queue> #include <map>using namespace std;const int maxn = 1000;vector<int> g[maxn];int n;void init () {for (int i=0; i<n; i++) G[i].clear ();} int current_cc;///connected component number void Dfs (int u) {vis[u] = 1; Cc[u] = CURRENT_CC; for (int i = 0; i < g[u].size (); i++) {int v = g[u][i]; if (!vis[v]) Dfs (v); }}void find_cc () {current_cc = 0; memset (vis,0,sizeof (VIS)); for (int u = 0; u < n; u++) {if (!vis[u]) {current_cc + +; DFS (U); }}}int Main () {int m, u, v; scanf ("%d%d", &n, &m); Init (); for (int i=0; i<m; i++) {cin>>u>>v; G[u].push_back (v); G[v].push_back (U); } find_cc (); for (int i = 0; i < n; i++) {///Assuming that the node is a 0-numbered printf ("node%d belongs to connected component%d\n", I,cc[i]); } return 0;}
2 cutting top and bridge without direction diagram
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include < cstring> #include <stack> #include <vector> #include <queue> #include <map>using namespace std;const int MAXN = 1000;vector<int> g[maxn];///g used to save figure int PRE[MAXN], dfs_clock, LOW[MAXN], N;///dfs_clock is timestamp, pre [] is used to hold the timestamp, that is, the node's access order///low[u] means that you and its descendants can be connected back to the earliest ancestor of the pre[] value///n is the number of nodes bool iscut[maxn];///determine if I node is not cut point vector< pair< int,int> > bridge;///used to save bridge Void Init () {for (int i=0; i<=n; i++) g[i].clear (); Memset (Iscut, False, sizeof (iscut)); memset (pre, 0, sizeof (pre)); Dfs_clock = 0; Bridge.clear ();} The timestamp is initialized to 0int dfs (int u, int fa) {///u The parent node in the Dfs tree is FA int Lowu = pre[u] = ++dfs_clock; int child = 0; The number of child nodes for (int i=0; i<g[u].size (); i++) {int v = g[u][i]; if (!pre[v]) {///has not visited V, it is not necessary to mark the child++ with Vis; int LOWV = DFS (v, u); Lowu = min (Lowu, LOWV); Updating the low function of u with the low function of descendants if (LOWV >= pre[u]) {Iscut[u] = true; if (Lowv > Pre[u]) {Bridge.push_back (Make_pair (u,v)); }}///the nature of the cut point} else if (Pre[v] < Pre[u] && v! = FA) {//(U,V) for reverse Edge Lowu = min ( Lowu, Pre[v]); Update U's low function with reverse edge} if (FA < 0 && child = = 1) Iscut[u] = false; } Low[u] = Lowu; return LOWU;} int main () {int m, u, v; scanf ("%d%d", &n, &m); Init (); for (int i=0; i<m; i++) {cin>>u>>v; G[u].push_back (v); G[v].push_back (U); } for (int i=0; i<n; i++) if (!pre[i]) {DFS (I,-1); }///The information of the cut point exists in the iscut[] array for (int i=0; i<n; i++) {///will cut output if (Iscut[i]) printf ("%d", I); } putchar (' \ n '); for (int i = 0; i < bridge.size (); i++) {///bridge Output printf ("%d%d\n", bridge[i].first,bridge[i].second); } return 0;}
Examples:
12 12
0 1
0 4
4 8
8 9
6 {
2 3
2 7
2 6
6 7
3 7
10 7
7 11
3 Two-connected components of undirected graphs
The bccno of the cut is meaningless: the bccno of the cut point is assigned multiple times, so its value is meaningless.
After the call is complete, S is guaranteed to be empty:
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include < cstring> #include <stack> #include <vector> #include <queue> #include <map>using namespace std;const int maxn = 1000+10;int PRE[MAXN], ISCUT[MAXN], BCCNO[MAXN], Dfs_clock, BCC_CNT;///BCCNO is the number of the two connected components each node belongs to///BCC _CNT is the number of two connected components vector<int> G[MAXN], the bcc[maxn];///bcc[] array records each of the two connected component struct edge{int u, v;}; stack<edge> s;int dfs (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 (v, u); Lowu = min (Lowu, LOWV); if (LOWV >= pre[u]) {Iscut[u] = true; bcc_cnt++; Bcc[bcc_cnt].clear (); for (;;) {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] = 0; return LOWU;} void find_bcc (int n) {memset (pre, 0, sizeof (pre)); memset (iscut, 0, sizeof (iscut)); memset (bccno, 0, sizeof (BCCNO)); Dfs_clock = bcc_cnt = 0; for (int i=0; i<n; i++) {if (!pre[i]) DFS (i,-1); }}int Main () {int m, u, V, n; scanf ("%d%d", &n, &m); for (int i=0; i<m; i++) {cin>>u>>v; G[u].push_back (v); G[v].push_back (U); } FIND_BCC (n); PrintF ("%d\n", bcc_cnt); The number of double-connected components for (int i=1; i<=bcc_cnt; i++) {///outputs each double-connected component for (int j=0; j<bcc[i].size (); j + +) {PR intf ("%d", bcc[i][j]); } putchar (' \ n '); } return 0;}
Examples:
5 6
0 1
0 2
1 2
2 3
2 4
3 4
4 strongly connected components of a forward graph
#include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <stack >using namespace Std;const int maxn = 2000;int PRE[MAXN], LOWLINK[MAXN], SCCNO[MAXN], Dfs_clock, scc_cnt;///lowlink[] Number The group is equivalent to the previous low[] array, and the other variables resemble vector<int> g[maxn];stack<int> s;void dfs (int u) {pre[u] = lowlink[u] = ++dfs_clock; S.push (U); for (int i=0; i<g[u].size (); i++) {int v = g[u][i]; if (!pre[v]) {DFS (v); Lowlink[u] = min (Lowlink[u], lowlink[v]); } else if (!sccno[v]) {Lowlink[u] = min (Lowlink[u], pre[v]); }} if (lowlink[u] = = Pre[u]) {scc_cnt++; for (;;) {int x = S.top (); S.pop (); SCCNO[X] = scc_cnt; if (x = = u) break; }}}void FIND_SCC (int n) {///stack is always empty without initialization Dfs_clock = scc_cnt = 0; memset (sccno, 0, sizeof (SCCNO)); memset (pre, 0, sizeof (pre)); for (int i=0; i<n; i++) {if (!pre[i]) DFS (i); }}int Main () {int n, m, U, v; scanf ("%d%d", &n, &m); for (int i=0; i<n; i++) g[i].clear (); for (int i=0; i<m; i++) {scanf ("%d%d", &u, &v); G[u].push_back (v); } FIND_SCC (n); Outputs all strongly connected components for (int i=1; i<=scc_cnt; i++) {for (int j=0; j<n; J + +) if (sccno[j] = = i) printf ("%d", j); Putchar (' \ n '); } return 0;}
Examples:
12 17
0 11 21 31 42 54 14 54 65 25 76 76 97 108 69 810 1111 9
The strongly connected components of a doubly connected component with a undirected graph of a connected component and a bridge without a direction graph