Comprobar si un gráfico tiene un ciclo de longitud impar

Dado un gráfico, la tarea es encontrar si tiene un ciclo de longitud impar o no.
 

Check if a graphs has a cycle of odd length

Check if a graphs has a cycle of odd length
 

La idea se basa en un hecho importante de que un gráfico no contiene un ciclo de longitud impar si y sólo si es bipartito , es decir, puede colorearse con dos colores.

Es obvio que si un gráfico tiene un ciclo de longitud impar, entonces no puede ser bipartito. En el gráfico bipartito hay dos conjuntos de vértices tales que ningún vértice de un conjunto está conectado con ningún otro vértice del mismo conjunto). Para un ciclo de longitud impar, dos vértices del mismo conjunto deben estar conectados, lo que contradice la definición bipartita.

Entendamos a la inversa, si un gráfico no tiene un ciclo impar, entonces debe ser bipartito. A continuación se muestra una prueba basada en inducción de esto tomada de http://infohost.nmt.edu/~math/faculty/barefoot/Math321Spring98/BipartiteGraphsAndEvenCycles.html

Suponga que (X, Y) es una bipartición de G y sea C = u 1 , u 2 , . . . , u k sea un ciclo de G , donde u 1 está en el conjunto de vértices X (abreviado u 1 ∈ X). Si u 1 ∈ X entonces u 2 ∈ Y, . . . y, en general, u 2j+1 ∈ X y u 2i ∈ Y. Como C es un ciclo, u k ∈ Y, de modo que k = 2 s para algún entero positivo s. Por lo tanto ciclo Cincluso.

Suponga que el gráfico G no tiene ciclos impares. Se demostrará que tal gráfico es bipartito. La demostración es por inducción sobre el número de aristas. La afirmación es claramente cierta para un gráfico con a lo sumo un borde. Suponga que todo grafo sin ciclos impares y como máximo q aristas es bipartito y sea G un grafo con q + 1 aristas y sin ciclos impares. Sea e = uv una arista de G y considere el gráfico H = G – uv. Por inducción, H tiene una bipartición (X, Y). Si e tiene un extremo en X y el otro en Y entonces ( X , Y) es una bipartición de G . Por lo tanto , suponga que u y v están en X. Si hubiera un camino, P , entre u y v en H , entonces la longitud de P sería par. Así, P + uv sería un ciclo impar de G. Por lo tanto, u y v deben estar en diferentes «piezas» o componentes de H . Así, tenemos:
 

donde X = X1 & X2 y Y = Y1 ∪ Y2 . En este caso es claro que ( X1 ∪ Y2, X2 ∪ Y1) es una bipartición de G.
 

Por lo tanto, concluimos que todo gráfico sin ciclos impares es bipartito. Se puede construir una bipartición de la siguiente manera: 

  1. Elija un vértice arbitrario x 0 y establezca X 0 = { x 0 }. 
  2. Sea Y 0 el conjunto de todos los vértices adyacentes a x 0 e itere los pasos 3-4. 
  3. Sea X k el conjunto de vértices no elegidos que son adyacentes a un vértice de Y k-1
  4. Sea Y k el conjunto de vértices no elegidos que son adyacentes a un vértice de X k-1
  5. Si se han elegido  todos los vértices de G , entonces

X = X 0 ∪ X 1 ∪ X 2 ∪. . . y Y = Y 0 ∪ Y 1 ∪ Y 2 ∪ . . .

A continuación se muestra el código para verificar si un gráfico tiene un ciclo impar o no. El código básicamente verifica si el gráfico es bipartito. 

C++

// C++ program to find out whether a given graph is
// Bipartite or not
#include <bits/stdc++.h>
#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 <int> 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<Integer> q = new LinkedList<Integer>();
        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<int> q = new Queue<int>();
        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

<script>
 
 
// JavaScript Code For Check if a graphs has a cycle
// of odd length
 
var V = 4;
 
// This function returns true if graph G[V,V]
// contains odd cycle, else false
function containsOdd(G, 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.
    var colorArr = Array(V).fill(-1);
     
    // Assign first color to source
    colorArr[src] = 1;
     
    // Create a queue (FIFO) of vertex numbers and
    // enqueue source vertex for BFS traversal
    var q = [];
    q.push(src);
     
    // Run while there are vertices in queue
    // (Similar to BFS)
    while (q.length != 0)
    {
        // Dequeue a vertex from queue
        var u = q[0];
        q.shift();
     
        // Return true if there is a self-loop
        if (G[u][u] == 1)
        return true;
     
        // Find all non-colored adjacent vertices
        for (var 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 code */
var G = [[0, 1, 0, 1],
            [1, 0, 1, 0],
            [0, 1, 0, 1],
            [1, 0, 1, 0]];
                             
if (containsOdd(G, 0))
    document.write("Yes") ;
else
    document.write("No");
 
 
</script>
Producción

No

El algoritmo anterior funciona solo si el gráfico está fuertemente conectado. Podemos extenderlo para los casos en que el gráfico no está fuertemente conectado (consulte esto para obtener más detalles). En el código anterior, siempre comenzamos con la fuente 0 y asumimos que se visitan los vértices desde ella. Una observación importante es que un gráfico sin bordes también es bipartito. Tenga en cuenta que la condición bipartita dice que todos los bordes deben ser de un conjunto a otro.

Este artículo es una contribución de Kartik . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks. 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *