检查图形是否具有奇数长度的循环
给定一个图,任务是找出它是否有一个奇数长度的循环。
这个想法是基于一个重要的事实,即一个图不包含一个奇数长度的循环当且仅当它是二分的,即它可以用两种颜色着色。
很明显,如果一个图有一个奇数长度的循环,那么它就不可能是二分图。在二分图中,有两组顶点,使得一个集合中的任何顶点都没有与同一集合的任何其他顶点相连)。对于奇数长度的循环,必须连接同一集合的两个顶点,这与二分定义相矛盾。
让我们理解一下,如果一个图没有奇数圈,那么它一定是二分图。下面是一个基于归纳的证明,取自 http://infohost.nmt.edu/~math/faculty/barefoot/Math321Spring98/BipartiteGraphsAndEvenCycles.html
假设 (X, Y) 是G的二分法,令C = u 1 , u 2 , . . . , u k是G的一个循环,其中u 1在顶点集 X 中(缩写为u 1 ∈ X)。如果u 1 ∈ X 那么u 2 ∈ Y, . . .并且,一般来说, u 2j+1 ∈ X 和u 2i ∈ Y。由于 C 是一个循环, u k ∈ Y,所以对于某个正整数 s, k = 2 s 。因此周期C是偶数。
假设图G没有奇数环。将证明这样的图是二分的。证明是对边数的归纳。对于最多具有一条边的图,该断言显然是正确的。假设每个没有奇数环且最多有q条边的图都是二分图,令G是一个有q + 1 条边且没有奇数环的图。设e = uv是G的一条边,并考虑图H = G – uv。通过归纳, H有一个二分 (X, Y)。如果e的一端在X中,另一端在Y中,则 ( X , Y ) 是G的二分法。因此,假设u和v在X中。如果在H中的u和v之间有一条路径P ,那么P的长度将是偶数。因此, P + uv将是G的奇数循环。因此, u和v必须位于H的不同“部分”或组件中。因此,我们有:
其中X = X1 & X2和Y = Y1 ∪ Y2 。在这种情况下,很明显 ( X1 ∪ Y2, X2 ∪ Y1)是G的二分法。
因此,我们得出结论,每个没有奇数循环的图都是二分的。可以按如下方式构造二分法:
(1) 选择任意一个顶点x 0并设置X 0 = { x 0 }。
(2) 令Y 0为与x 0相邻的所有顶点的集合,并迭代步骤 3-4。
(3) 令X k是与Y k-1的顶点相邻的未选择的顶点集合。
(4) 令Y k为与X k-1的顶点相邻的未选择的顶点集合。
(5) 如果G的所有顶点都被选中,那么
X = X 0 ∪ X 1 ∪ X 2 ∪。 . .和Y = Y 0 ∪ Y 1 ∪ Y 2 ∪ 。 . .
下面是检查图形是否具有奇数循环的代码。该代码基本上检查图是否为二分图。
C++
// C++ program to find out whether a given graph is
// Bipartite or not
#include
#define V 4
using namespace std;
// This function returns true if graph G[V][V] contains
// odd cycle, else false
bool containsOdd(int G[][V], int src)
{
// Create a color array to store colors assigned
// to all vertices. Vertex number is used as index
// in this array. The value '-1' of colorArr[i]
// is used to indicate that no color is assigned to
// vertex 'i'. The value 1 is used to indicate first
// color is assigned and value 0 indicates second
// color is assigned.
int colorArr[V];
for (int i = 0; i < V; ++i)
colorArr[i] = -1;
// Assign first color to source
colorArr[src] = 1;
// Create a queue (FIFO) of vertex numbers and
// enqueue source vertex for BFS traversal
queue q;
q.push(src);
// Run while there are vertices in queue (Similar to BFS)
while (!q.empty())
{
// Dequeue a vertex from queue
int u = q.front();
q.pop();
// Return true if there is a self-loop
if (G[u][u] == 1)
return true;
// Find all non-colored adjacent vertices
for (int v = 0; v < V; ++v)
{
// An edge from u to v exists and destination
// v is not colored
if (G[u][v] && colorArr[v] == -1)
{
// Assign alternate color to this adjacent
// v of u
colorArr[v] = 1 - colorArr[u];
q.push(v);
}
// An edge from u to v exists and destination
// v is colored with same color as u
else if (G[u][v] && colorArr[v] == colorArr[u])
return true;
}
}
// If we reach here, then all adjacent
// vertices can be colored with alternate
// color
return false;
}
// Driver program to test above function
int main()
{
int G[][V] = {{0, 1, 0, 1},
{1, 0, 1, 0},
{0, 1, 0, 1},
{1, 0, 1, 0}
};
containsOdd(G, 0) ? cout << "Yes" : cout << "No";
return 0;
}
Java
// JAVA Code For Check if a graphs has a cycle
// of odd length
import java.util.*;
class GFG {
public static int V =4;
// This function returns true if graph G[V][V]
// contains odd cycle, else false
public static boolean containsOdd(int G[][], int src)
{
// Create a color array to store colors assigned
// to all vertices. Vertex number is used as
// index in this array. The value '-1' of
// colorArr[i] is used to indicate that no color
// is assigned to vertex 'i'. The value 1 is
// used to indicate first color is assigned and
// value 0 indicates second color is assigned.
int colorArr[] = new int[V];
for (int i = 0; i < V; ++i)
colorArr[i] = -1;
// Assign first color to source
colorArr[src] = 1;
// Create a queue (FIFO) of vertex numbers and
// enqueue source vertex for BFS traversal
LinkedList q = new LinkedList();
q.add(src);
// Run while there are vertices in queue
// (Similar to BFS)
while (!q.isEmpty())
{
// Dequeue a vertex from queue
int u = q.peek();
q.pop();
// Return true if there is a self-loop
if (G[u][u] == 1)
return true;
// Find all non-colored adjacent vertices
for (int v = 0; v < V; ++v)
{
// An edge from u to v exists and
// destination v is not colored
if (G[u][v] == 1 && colorArr[v] == -1)
{
// Assign alternate color to this
// adjacent v of u
colorArr[v] = 1 - colorArr[u];
q.push(v);
}
// An edge from u to v exists and
// destination v is colored with same
// color as u
else if (G[u][v] == 1 && colorArr[v] ==
colorArr[u])
return true;
}
}
// If we reach here, then all adjacent
// vertices can be colored with alternate
// color
return false;
}
/* Driver program to test above function */
public static void main(String[] args)
{
int G[][] = {{0, 1, 0, 1},
{1, 0, 1, 0},
{0, 1, 0, 1},
{1, 0, 1, 0}};
if (containsOdd(G, 0))
System.out.println("Yes") ;
else
System.out.println("No");
}
}
// This code is contributed by Arnav Kr. Mandal.
Python3
# Python3 program to find out whether
# a given graph is Bipartite or not
import queue
# This function returns true if graph
# G[V][V] contains odd cycle, else false
def containsOdd(G, src):
global V
# Create a color array to store
# colors assigned to all vertices.
# Vertex number is used as index
# in this array. The value '-1' of
# colorArr[i] is used to indicate
# that no color is assigned to vertex
# 'i'. The value 1 is used to indicate
# first color is assigned and value 0
# indicates second color is assigned.
colorArr = [-1] * V
# Assign first color to source
colorArr[src] = 1
# Create a queue (FIFO) of vertex
# numbers and enqueue source vertex
# for BFS traversal
q = queue.Queue()
q.put(src)
# Run while there are vertices in
# queue (Similar to BFS)
while (not q.empty()):
# Dequeue a vertex from queue
u = q.get()
# Return true if there is a self-loop
if (G[u][u] == 1):
return True
# Find all non-colored adjacent vertices
for v in range(V):
# An edge from u to v exists and
# destination v is not colored
if (G[u][v] and colorArr[v] == -1):
# Assign alternate color to this
# adjacent v of u
colorArr[v] = 1 - colorArr[u]
q.put(v)
# An edge from u to v exists and
# destination v is colored with
# same color as u
elif (G[u][v] and
colorArr[v] == colorArr[u]):
return True
# If we reach here, then all
# adjacent vertices can be
# colored with alternate color
return False
# Driver Code
V = 4
G = [[0, 1, 0, 1],
[1, 0, 1, 0],
[0, 1, 0, 1],
[1, 0, 1, 0]]
if containsOdd(G, 0):
print("Yes")
else:
print("No")
# This code is contributed by PranchalK
C#
// C# Code For Check if a graphs has a cycle
// of odd length
using System;
using System.Collections.Generic;
class GFG
{
public static int V = 4;
// This function returns true if graph G[V,V]
// contains odd cycle, else false
public static bool containsOdd(int [,]G, int src)
{
// Create a color array to store colors assigned
// to all vertices. Vertex number is used as
// index in this array. The value '-1' of
// colorArr[i] is used to indicate that no color
// is assigned to vertex 'i'. The value 1 is
// used to indicate first color is assigned and
// value 0 indicates second color is assigned.
int []colorArr = new int[V];
for (int i = 0; i < V; ++i)
colorArr[i] = -1;
// Assign first color to source
colorArr[src] = 1;
// Create a queue (FIFO) of vertex numbers and
// enqueue source vertex for BFS traversal
Queue q = new Queue();
q.Enqueue(src);
// Run while there are vertices in queue
// (Similar to BFS)
while (q.Count != 0)
{
// Dequeue a vertex from queue
int u = q.Peek();
q.Dequeue();
// Return true if there is a self-loop
if (G[u, u] == 1)
return true;
// Find all non-colored adjacent vertices
for (int v = 0; v < V; ++v)
{
// An edge from u to v exists and
// destination v is not colored
if (G[u, v] == 1 && colorArr[v] == -1)
{
// Assign alternate color to this
// adjacent v of u
colorArr[v] = 1 - colorArr[u];
q.Enqueue(v);
}
// An edge from u to v exists and
// destination v is colored with same
// color as u
else if (G[u,v] == 1 && colorArr[v] ==
colorArr[u])
return true;
}
}
// If we reach here, then all adjacent
// vertices can be colored with alternate
// color
return false;
}
/* Driver code */
public static void Main()
{
int [,]G = {{0, 1, 0, 1},
{1, 0, 1, 0},
{0, 1, 0, 1},
{1, 0, 1, 0}};
if (containsOdd(G, 0))
Console.WriteLine("Yes") ;
else
Console.WriteLine("No");
}
}
// This code has been contributed by 29AjayKumar
Javascript
输出:
No