Grade 11 · Undirected graphsCitește în română
Checking a bipartite graph
Original: Verificarea unui graf bipartit
The idea
A graph is bipartite if its nodes can be split into two sets A and B so that every edge has one end in A and the other in B. We color the nodes with two colors using BFS: the start node gets color 1, and every neighbour gets the color opposite to the node it was discovered from. If we find an edge with both ends of the same color, the graph is not bipartite (it has an odd-length cycle). We start BFS from every uncolored node, so disconnected graphs are handled too.
Original description (Romanian)
Un graf este bipartit dacă nodurile lui se pot împărți în două mulțimi A și B astfel încât fiecare muchie să aibă un capăt în A și celălalt în B. Colorăm nodurile cu două culori printr-o parcurgere BFS: nodul de start primește culoarea 1, iar fiecare vecin primește culoarea opusă nodului din care a fost descoperit. Dacă găsim o muchie cu ambele capete de aceeași culoare, graful nu e bipartit (are un ciclu de lungime impară). Pornim BFS din fiecare nod necolorat, ca să tratăm și grafurile neconexe.
- Complexity
- O(n²) with the adjacency matrix
- Grade
- Grade 11 (Clasa a XI-a)
- Chapter
- Undirected graphs
Examples
Input
6 6 1 2 2 3 3 4 4 1 4 5 5 6
Expected output
DA 1 3 5 2 4 6
Input
3 3 1 2 2 3 3 1
Expected output
NU
The code
Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.
/*
* Titlu: Verificarea unui graf bipartit
* Clasa: 11
* Capitol: Grafuri neorientate
* Descriere: Un graf este bipartit dacă nodurile lui se pot împărți în două mulțimi A și B
* astfel încât fiecare muchie să aibă un capăt în A și celălalt în B. Colorăm
* nodurile cu două culori printr-o parcurgere BFS: nodul de start primește
* culoarea 1, iar fiecare vecin primește culoarea opusă nodului din care a fost
* descoperit. Dacă găsim o muchie cu ambele capete de aceeași culoare, graful nu
* e bipartit (are un ciclu de lungime impară). Pornim BFS din fiecare nod
* necolorat, ca să tratăm și grafurile neconexe.
* Complexitate: O(n²) cu matricea de adiacență
*
* Exemplu
* Intrare:
* 6 6
* 1 2
* 2 3
* 3 4
* 4 1
* 4 5
* 5 6
* Ieșire:
* DA
* 1 3 5
* 2 4 6
*
* Exemplu
* Intrare:
* 3 3
* 1 2
* 2 3
* 3 1
* Ieșire: NU
*/
#include <iostream>
using namespace std;
int n, m, a[105][105], culoare[105], coada[105];
int main()
{
cin >> n >> m;
for (int k = 1; k <= m; k++)
{
int x, y;
cin >> x >> y;
a[x][y] = a[y][x] = 1;
}
bool bipartit = true;
for (int s = 1; s <= n && bipartit; s++)
{
if (culoare[s] != 0)
{
continue;
}
int inc = 1, sf = 1;
coada[1] = s;
culoare[s] = 1;
while (inc <= sf && bipartit)
{
int x = coada[inc++];
for (int y = 1; y <= n; y++)
{
if (a[x][y] == 1)
{
if (culoare[y] == 0)
{
culoare[y] = 3 - culoare[x];
coada[++sf] = y;
}
else if (culoare[y] == culoare[x])
{
bipartit = false;
}
}
}
}
}
if (!bipartit)
{
cout << "NU\n";
return 0;
}
cout << "DA\n";
for (int c = 1; c <= 2; c++)
{
for (int i = 1; i <= n; i++)
{
if (culoare[i] == c)
{
cout << i << ' ';
}
}
cout << '\n';
}
return 0;
}
Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.