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;
}
