First, I understand several theorems:
- Connected Component: undirected graphGIs calledGOneConnected Component(OrConnected Branch). A connected graph has only one connected component, that is, itself. An unconnected undirected graph has multiple connected components.
- Strongly Connected Graph: Directed GraphG= (V,E), If any two different vertices in VXAndY, All exist fromXToYAndYToXIs calledGYesStrongly Connected Graph
Graph). CorrespondinglyStronugly connected component). A strongly connected graph has only one strongly connected component, that is, its own. A non-strongly connected directed graph has multiple strongly connected components.
1. Determine the connectivity of an undirected graph.
Use BFS or DFS to traverse. If you can traverse all nodes, It is a connected graph.
For example, the easiest way to think of a set of cut points that require an undirected graph is to test each node in sequence to determine its impact on Graph connectivity.
There are simpler methods.
2. Single connectivity of Directed Graphs. For any two points, I, J, there is a path from I to J or J to I
1. The most common algorithm is the Floyd algorithm.
The Floyd algorithm is used to obtain the shortest path between any two points in the figure. The general idea is:
Take each vertex K as the intermediate node of I ---> J, and calculate d (I, j) = min (d (I, j), D (I, K) + d (K, j ))
If the Floyd algorithm is used to determine the connectivity between any two points?
You can directly use the above algorithm, but you can convert addition and Min operations into bit operations.
D (I, j) = d (I, j) | (d (I, k) & D (K, j ))
2. the time complexity of the above algorithm is O (n ^ 3)
Http://hi.baidu.com/735612658gfy/item/e2e8c8d3362fa9f2b3f7777b
Idea: You can use the Tarjan algorithm to determine whether a directed graph is strongly connected.
However, it is troublesome to determine whether one-way Unicom is used.
At first I wanted to use Floyd, and later I thought of finding a path, but these two methods are too complex.
Positive Solution: For a dag, if it is one-way Unicom, we can have such a property that there is a path that can go through every point in the figure. The following is a proof.
If we select a point A with an inbound value of 0 and a point B with an outbound value of 0, the remaining points must be between A and B.
Find K, then ~ K ~ B. The remaining points must be in two places ~ And so on.
Let's first turn this figure into a dag. We use the Tarjan algorithm to reduce the point, and this graph becomes a Dag.
# Include <cstdio> # include <iostream> # include <cstring> # include <stack> using namespace STD; stack <int> S; struct HH {int U, V, next;} TP [6005], map [6006]; int head [1050], mhead [1050], num, mnum, low [1050], Lp [1050], now, f [1050]; bool in [1050]; int n, m, step, total; void add (int A, int B) {TP [num]. U = A; TP [num]. V = B; TP [num]. next = head [a]; head [a] = num ++;} void MADD (int A, int B) {map [mnum]. U = A; Map [mnum]. V = B; Map [mnum]. Next = mhead [a]; mhead [a] = mnum ++;} void Init () {int A, B; num = 0; mnum = 0; step = Total = 1; while (! S. empty () s. pop (); For (INT I = 1; I <= N; I ++) {in [I] = 0; low [I] = Lp [I] = f [I] = 0;} memset (Head,-1, sizeof (head); memset (mhead,-1, sizeof (mhead); scanf ("% d", & N, & M); For (INT I = 0; I <m; I ++) {scanf ("% d", & A, & B); add (a, B) ;}} void Tarjan (INT U) {int V; low [u] = Lp [u] = Step ++; S. push (U); in [u] = 1; for (INT I = head [u]; I! =-1; I = TP [I]. Next) {v = TP [I]. V; If (! Low [v]) {Tarjan (V); low [u] = min (low [u], low [v]);} else if (in [v]) {LOW [u] = min (low [u], Lp [v]) ;}} if (low [u] = Lp [u]) {int Haha; while (1) {Haha = S. top (); S. pop (); F [Haha] = total; in [Haha] = 0; If (haha = u) break;} total ++ ;}} void suodian () {for (INT I = 0; I <num; I ++) {If (F [TP [I]. u]! = F [TP [I]. v]) MADD (F [TP [I]. u], F [TP [I]. v]) ;}} bool can [1004] [1004]; int B [1050]; bool DFS (INT U, int now) {in [u] = 1; if (now = total-1) return true; bool flag = 0; For (INT I = mhead [u]; I! =-1; I = map [I]. next) {flag = DFS (Map [I]. v, now + 1); If (FLAG) return true;} return false;} void result () {memset (in, 0, sizeof (in )); for (INT I = 1; I <= N; I ++) {If (! In [I]) {bool flag = DFS (I, 1); {If (FLAG) {cout <"yes" <Endl; return ;}}}} cout <"no" <Endl;} int main () {int t; scanf ("% d", & T); While (t --) {Init (); for (INT I = 1; I <= N; I ++) if (! Low [I]) Tarjan (I); suodian (); // recreate the graph result ();}}
You can also use the above algorithm to find the single connected branch of the directed graph. If the inbound degree is 0, Recursively search for each forward path to the point where each vertex cannot be moved forward, a single connected branch can be obtained.