📌  相关文章
📜  检查图形是否具有奇数长度的循环

📅  最后修改于: 2022-05-13 01:57:54.104000             🧑  作者: Mango

检查图形是否具有奇数长度的循环

给定一个图,任务是找出它是否有一个奇数长度的循环。

检查图形是否具有奇数长度的循环

检查图形是否具有奇数长度的循环

这个想法是基于一个重要的事实,即一个图包含一个奇数长度的循环当且仅当它是二分的,即它可以用两种颜色着色。
很明显,如果一个图有一个奇数长度的循环,那么它就不可能是二分图。在二分图中,有两组顶点,使得一个集合中的任何顶点都没有与同一集合的任何其他顶点相连)。对于奇数长度的循环,必须连接同一集合的两个顶点,这与二分定义相矛盾。
让我们理解一下,如果一个图没有奇数圈,那么它一定是二分图。下面是一个基于归纳的证明,取自 http://infohost.nmt.edu/~math/faculty/barefoot/Math321Spring98/BipartiteGraphsAndEvenCycles.html
假设 (X, Y) 是G的二分法,令C = u 1 , u 2 , . . . , u kG的一个循环,其中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 = uvG的一条边,并考虑图H = G – uv。通过归纳, H有一个二分 (X, Y)。如果e的一端在X中,另一端在Y中,则 ( X , Y ) 是G的二分法。因此,假设uvX中。如果在H中的uv之间有一条路径P ,那么P的长度将是偶数。因此, P + uv将是G的奇数循环。因此, uv必须位于H的不同“部分”或组件中。因此,我们有:

其中X = X1 & X2Y = 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