Editorial
Using depth-first search, we can calculate the number of connected components. If it equals , the graph is connected.
Another solution is to start a depth-first search from vertex and count the number of visited vertices. If it equals , the graph is connected.
Example
Graphs given in example, have the form:
Algorithm realization
Declare the adjacency matrix and the array of visited vertices .
#define MAX 101 int g[MAX][MAX], used[MAX];
The dfs function performs a depth-first search starting from vertex .
void dfs(int v) { used[v] = 1; for (int i = 1; i <= n; i++) if (g[v][i] && !used[i]) dfs(i); }
The main part of the program. Read the input data.
scanf("%d %d", &n, &m);
Initialize the arrays.
memset(g,0,sizeof(g)); memset(used,0,sizeof(used));
Сonstruct the adjacency matrix of the graph.
for (i = 0; i < m; i++) { scanf("%d %d", &a, &b); g[a][b] = g[b][a] = 1; }
The number of connected components is stored in the variable .
cnt = 0;
Start a depth-first search on a disconnected graph.
for (i = 1; i <= n; i++) if (!used[i]) {
The number of dfs function calls equals the number of connected components in the graph.
dfs(i); cnt++; }
Print the result. If the graph has only one connected component, it is connected.
if (cnt == 1) printf("YES\n"); else printf("NO\n");
Algorithm realization — the number of visited vertices
Declare the adjacency matrix and the array of visited vertices .
#define MAX 101 int g[MAX][MAX], used[MAX];
The dfs function performs a depth-first search starting from vertex . The variable keeps track of the number of visited vertices.
void dfs(int v) { used[v] = 1; cnt++; for (int i = 1; i <= n; i++) if ((g[v][i] == 1) && (used[i] == 0)) dfs(i); }
The main part of the program. Read the input data.
scanf("%d %d", &n,&m);
Initialize the arrays.
memset(g, 0, sizeof(g)); memset(used, 0, sizeof(used));
Сonstruct the adjacency matrix of the graph.
for (i = 0; i < m; i++) { scanf("%d %d", &a, &b); g[a][b] = g[b][a] = 1; }
Start a depth-first search from vertex .
cnt = 0; dfs(1);
If the depth-first search visits all vertices, then the graph is connected.
if (cnt == n) printf("YES\n"); else printf("NO\n");
Algorithm realization — disjoint sets union
Declare an array.
#define MAX 102 int mas[MAX];
The Repr function returns the representative of the set that contains vertex . We move along the pointer to the next element until we encounter the representative of the set (whose pointer points to itself).
int Repr(int n) { while (n != mas[n]) n = mas[n]; return n; }
The Union function merges two sets containing vertices and . Find the representatives of the sets containing and . Let these representatives be and . If , then and are already in the same set, and no further action is needed. Otherwise, we redirect the pointer of representative to .
void Union(int x, int y) { int x1 = Repr(x), y1 = Repr(y); if (x1 == y1) return; mas[x1] = y1; }
The main part of the program. Read the input data.
scanf("%d %d", &n, &m);
Initially, each vertex points to itself ().
for (i = 1; i <= n; i++) mas[i] = i;
Read the edges of the graph. For each edge , perform the union of the sets containing vertices and .
for (i = 1; i <= m; i++) { scanf("%d %d", &a, &b); Union(a, b); }
Count the number of connected components in the variable . This number equals the number of vertices that are representatives of their own sets (i.e., the vertices whose pointers point to themselves).
count = 0; for (i = 1; i <= n; i++) if (mas[i] == i) count++;
Based on the value of the variable, print the result.
if (count == 1) printf("YES\n"); else printf("NO\n");
Python realization
The dfs function performs a depth-first search starting from vertex .
def dfs(v): used[v] = 1 for i in range(1, n + 1): if g[v][i] and not used[i]: dfs(i)
The main part of the program. Read the input data.
n, m = map(int, input().split())
Initialize the lists.
g = [[0] * (n + 1) for _ in range(n + 1)] used = [0] * (n + 1)
Сonstruct the adjacency matrix of the graph.
for i in range(m): a, b = map(int, input().split()) g[a][b] = g[b][a] = 1
The number of connected components is stored in the variable .
cnt = 0
Start a depth-first search on a disconnected graph.
for i in range(1, n + 1): if not used[i]:
The number of dfs function calls equals the number of connected components in the graph.
dfs(i) cnt += 1
Print the result. If the graph has only one connected component, it is connected.
if cnt == 1: print("YES") else: print("NO")
Python realization — the number of visited vertices
The dfs function performs a depth-first search starting from vertex . The variable keeps track of the number of visited vertices.
def dfs(v): used[v] = 1 global cnt cnt += 1 for i in range(1, n + 1): if g[v][i] and not used[i]: dfs(i)
The main part of the program. Read the input data.
n, m = map(int, input().split())
Initialize the lists.
g = [[0] * (n + 1) for _ in range(n + 1)] used = [0] * (n + 1)
Сonstruct the adjacency matrix of the graph.
for i in range(m): a, b = map(int, input().split()) g[a][b] = g[b][a] = 1
Start a depth-first search from vertex .
cnt = 0 dfs(1)
If the depth-first search visits all vertices, then the graph is connected.
if cnt == n: print("YES") else: print("NO")
Python realization — disjoint sets union
The Repr function returns the representative of the set that contains vertex . We move along the pointer to the next element until we encounter the representative of the set (whose pointer points to itself).
def Repr(n): while n != mas[n]: n = mas[n] return n
The Union function merges two sets containing vertices and . Find the representatives of the sets containing and . Let these representatives be and . If , then and are already in the same set, and no further action is needed. Otherwise, we redirect the pointer of representative to .
def Union(x, y): x1 = Repr(x) y1 = Repr(y) if x1 == y1: return mas[x1] = y1
The main part of the program. Read the input data.
n, m = map(int, input().split())
Initially, each vertex points to itself ().
mas = [0] * (n + 1) for i in range(1, n + 1): mas[i] = i
Read the edges of the graph. For each edge , perform the union of the sets containing vertices and .
for _ in range(m): a, b = map(int, input().split()) Union(a, b)
Count the number of connected components in the variable . This number equals the number of vertices that are representatives of their own sets (i.e., the vertices whose pointers point to themselves).
count = 0 for i in range(1, n + 1): if mas[i] == i: count += 1
Based on the value of the variable, print the result.
if count == 1: print("YES") else: print("NO")