Grafos Avanzadosc++grafo bipartitocoloraciónmatching

Grafos Bipartitos

Identifica y trabaja con grafos que se pueden dividir en dos grupos

OOI Oaxaca9 de febrero de 20263 min read

¿Qué es un grafo bipartito?

Un grafo es bipartito si puedes dividir sus nodos en dos grupos (A y B) de modo que todas las aristas van de un grupo al otro (nunca dentro del mismo grupo).

Analogía: Piensa en un baile donde hay hombres y mujeres. Si solo se forman parejas hombre-mujer, la red de parejas es un grafo bipartito.

Grupo A: {1, 3, 5}     Grupo B: {2, 4, 6}

1 --- 2
|     |
3 --- 4
|     |
5 --- 6

Verificar si es bipartito: coloración con BFS

Intenta colorear el grafo con 2 colores. Si en algún momento un vecino ya tiene el mismo color, no es bipartito.

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> adj[100005];
int color[100005];  // -1 = sin color

bool esBipartito(int inicio) {
    queue<int> q;
    q.push(inicio);
    color[inicio] = 0;

    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int v : adj[u]) {
            if (color[v] == -1) {
                color[v] = 1 - color[u];
                q.push(v);
            } else if (color[v] == color[u]) {
                return false;
            }
        }
    }
    return true;
}

int main() {
    int n, m;
    cin >> n >> m;

    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    fill(color, color + n + 1, -1);

    bool bipartito = true;
    for (int i = 1; i <= n; i++) {
        if (color[i] == -1) {
            if (!esBipartito(i)) {
                bipartito = false;
                break;
            }
        }
    }

    cout << (bipartito ? "Es bipartito" : "No es bipartito") << endl;
    return 0;
}

Propiedad: Un grafo es bipartito si y solo si no tiene ciclos de longitud impar.

Ejercicio de práctica

Dado un grafo, determina si es bipartito. Si sí, imprime los dos grupos.

Ver solución
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

vector<int> adj[100005];
int color[100005];

int main() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    fill(color, color + n + 1, -1);
    bool ok = true;

    for (int i = 1; i <= n && ok; i++) {
        if (color[i] != -1) continue;
        queue<int> q;
        q.push(i);
        color[i] = 0;
        while (!q.empty() && ok) {
            int u = q.front(); q.pop();
            for (int v : adj[u]) {
                if (color[v] == -1) {
                    color[v] = 1 - color[u];
                    q.push(v);
                } else if (color[v] == color[u]) {
                    ok = false;
                }
            }
        }
    }

    if (!ok) {
        cout << "No es bipartito" << endl;
    } else {
        cout << "Grupo 0: ";
        for (int i = 1; i <= n; i++) if (color[i] == 0) cout << i << " ";
        cout << endl << "Grupo 1: ";
        for (int i = 1; i <= n; i++) if (color[i] == 1) cout << i << " ";
        cout << endl;
    }
    return 0;
}