无向连通图中长度为 n 的环
给定一个无向连通图和一个数字 n,计算图中长度为 n 的循环的总数。长度为 n 的循环仅表示该循环包含 n 个顶点和 n 个边。我们必须计算所有存在的此类周期。
示例:
Input : n = 4
Output : Total cycles = 3
Explanation : Following 3 unique cycles
0 -> 1 -> 2 -> 3 -> 0
0 -> 1 -> 4 -> 3 -> 0
1 -> 2 -> 3 -> 4 -> 1
Note* : There are more cycles but
these 3 are unique as 0 -> 3 -> 2 -> 1
-> 0 and 0 -> 1 -> 2 -> 3 -> 0 are
same cycles and hence will be counted as 1.
为了解决这个问题,可以有效地使用DFS(深度优先搜索)。使用 DFS,我们为特定源(或起点)找到长度为 (n-1) 的所有可能路径。然后我们检查这条路径是否以它开始的顶点结束,如果是,那么我们将其视为长度为 n 的循环。请注意,我们寻找长度为 (n-1) 的路径,因为第n条边将是循环的结束边。
可以仅使用V – ( n – 1 ) 个顶点(其中 V 是顶点的总数)来搜索长度为 (n-1) 的每个可能路径。
对于上面的示例,可以仅使用 5-(4-1) = 2 个顶点搜索所有长度为 4 的循环。这背后的原因很简单,因为我们使用这 2 个顶点(包括其余 3 个顶点)来搜索长度为 (n-1) = 3 的所有可能路径。因此,这 2 个顶点也覆盖了剩余 3 个顶点的循环,并且仅使用 3 个顶点我们无论如何都无法形成长度为 4 的循环。
还有一点需要注意的是,每个顶点为它形成的每个循环找到 2 个重复循环。对于上面的例子,第 0个顶点找到两个重复的循环,即0 -> 3 -> 2 -> 1 -> 0和0 -> 1 -> 2 -> 3 -> 0 。因此,总计数必须除以 2,因为每个周期都计算两次。
C++
// CPP Program to count cycles of length n
// in a given graph.
#include
using namespace std;
// Number of vertices
const int V = 5;
void DFS(bool graph[][V], bool marked[], int n,
int vert, int start, int &count)
{
// mark the vertex vert as visited
marked[vert] = true;
// if the path of length (n-1) is found
if (n == 0) {
// mark vert as un-visited to make
// it usable again.
marked[vert] = false;
// Check if vertex vert can end with
// vertex start
if (graph[vert][start])
{
count++;
return;
} else
return;
}
// For searching every possible path of
// length (n-1)
for (int i = 0; i < V; i++)
if (!marked[i] && graph[vert][i])
// DFS for searching path by decreasing
// length by 1
DFS(graph, marked, n-1, i, start, count);
// marking vert as unvisited to make it
// usable again.
marked[vert] = false;
}
// Counts cycles of length N in an undirected
// and connected graph.
int countCycles(bool graph[][V], int n)
{
// all vertex are marked un-visited initially.
bool marked[V];
memset(marked, 0, sizeof(marked));
// Searching for cycle by using v-n+1 vertices
int count = 0;
for (int i = 0; i < V - (n - 1); i++) {
DFS(graph, marked, n-1, i, i, count);
// ith vertex is marked as visited and
// will not be visited again.
marked[i] = true;
}
return count/2;
}
int main()
{
bool graph[][V] = {{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0}};
int n = 4;
cout << "Total cycles of length " << n << " are "
<< countCycles(graph, n);
return 0;
}
Java
// Java program to calculate cycles of
// length n in a given graph
public class Main {
// Number of vertices
public static final int V = 5;
static int count = 0;
static void DFS(int graph[][], boolean marked[],
int n, int vert, int start) {
// mark the vertex vert as visited
marked[vert] = true;
// if the path of length (n-1) is found
if (n == 0) {
// mark vert as un-visited to
// make it usable again
marked[vert] = false;
// Check if vertex vert end
// with vertex start
if (graph[vert][start] == 1) {
count++;
return;
} else
return;
}
// For searching every possible
// path of length (n-1)
for (int i = 0; i < V; i++)
if (!marked[i] && graph[vert][i] == 1)
// DFS for searching path by
// decreasing length by 1
DFS(graph, marked, n-1, i, start);
// marking vert as unvisited to make it
// usable again
marked[vert] = false;
}
// Count cycles of length N in an
// undirected and connected graph.
static int countCycles(int graph[][], int n) {
// all vertex are marked un-visited
// initially.
boolean marked[] = new boolean[V];
// Searching for cycle by using
// v-n+1 vertices
for (int i = 0; i < V - (n - 1); i++) {
DFS(graph, marked, n-1, i, i);
// ith vertex is marked as visited
// and will not be visited again
marked[i] = true;
}
return count / 2;
}
// driver code
public static void main(String[] args) {
int graph[][] = {{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0}};
int n = 4;
System.out.println("Total cycles of length "+
n + " are "+
countCycles(graph, n));
}
}
// This code is contributed by nuclode
Python3
# Python Program to count
# cycles of length n
# in a given graph.
# Number of vertices
V = 5
def DFS(graph, marked, n, vert, start, count):
# mark the vertex vert as visited
marked[vert] = True
# if the path of length (n-1) is found
if n == 0:
# mark vert as un-visited to make
# it usable again.
marked[vert] = False
# Check if vertex vert can end with
# vertex start
if graph[vert][start] == 1:
count = count + 1
return count
else:
return count
# For searching every possible path of
# length (n-1)
for i in range(V):
if marked[i] == False and graph[vert][i] == 1:
# DFS for searching path by decreasing
# length by 1
count = DFS(graph, marked, n-1, i, start, count)
# marking vert as unvisited to make it
# usable again.
marked[vert] = False
return count
# Counts cycles of length
# N in an undirected
# and connected graph.
def countCycles( graph, n):
# all vertex are marked un-visited initially.
marked = [False] * V
# Searching for cycle by using v-n+1 vertices
count = 0
for i in range(V-(n-1)):
count = DFS(graph, marked, n-1, i, i, count)
# ith vertex is marked as visited and
# will not be visited again.
marked[i] = True
return int(count/2)
# main :
graph = [[0, 1, 0, 1, 0],
[1 ,0 ,1 ,0, 1],
[0, 1, 0, 1, 0],
[1, 0, 1, 0, 1],
[0, 1, 0, 1, 0]]
n = 4
print("Total cycles of length ",n," are ",countCycles(graph, n))
# this code is contributed by Shivani Ghughtyal
C#
// C# program to calculate cycles of
// length n in a given graph
using System;
class GFG
{
// Number of vertices
public static int V = 5;
static int count = 0;
static void DFS(int [,]graph, bool []marked,
int n, int vert, int start)
{
// mark the vertex vert as visited
marked[vert] = true;
// if the path of length (n-1) is found
if (n == 0)
{
// mark vert as un-visited to
// make it usable again
marked[vert] = false;
// Check if vertex vert end
// with vertex start
if (graph[vert, start] == 1)
{
count++;
return;
}
else
return;
}
// For searching every possible
// path of length (n-1)
for (int i = 0; i < V; i++)
if (!marked[i] && graph[vert, i] == 1)
// DFS for searching path by
// decreasing length by 1
DFS(graph, marked, n - 1, i, start);
// marking vert as unvisited to make it
// usable again
marked[vert] = false;
}
// Count cycles of length N in an
// undirected and connected graph.
static int countCycles(int [,]graph, int n)
{
// all vertex are marked un-visited
// initially.
bool []marked = new bool[V];
// Searching for cycle by using
// v-n+1 vertices
for (int i = 0; i < V - (n - 1); i++)
{
DFS(graph, marked, n - 1, i, i);
// ith vertex is marked as visited
// and will not be visited again
marked[i] = true;
}
return count / 2;
}
// Driver code
public static void Main()
{
int [,]graph = {{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0},
{1, 0, 1, 0, 1},
{0, 1, 0, 1, 0}};
int n = 4;
Console.WriteLine("Total cycles of length "+
n + " are "+
countCycles(graph, n));
}
}
/* This code contributed by PrinciRaj1992 */
Javascript
输出:
Total cycles of length 4 are 3