У задачі слід перевірити, чи можна розфарбувати граф у кольори так, щоб будь-які дві сусідні вершини мали різні кольори. Такий граф називається двочастковим.
Якщо здійснити пошук у глибину на графі, то:
Нехай перша вершина має колір ;
Тоді всі її сусіди повинні мати колір ;
Сусіди вершин з кольором повинні знову мати колір ;
І так далі...
Тобто кольори вершин повинні чергуватися за глибиною обходу.
Для розв'язання задачі скористаємось пошуком у глибину. Спочатку всі вершини вважаються невідвіданими і позначаються кольором . У процесі обходу графа будемо розфарбовувати вершини у два кольори: і . Якщо поточна вершина має колір (де i = 1 або ), то кожну наступну вершину, в яку ми переходимо при обході в глибину, фарбуємо в колір 3 - i. При цьому на кожному кроці перевіряємо, щоб жодні дві суміжні вершини не були пофарбовані в один і той же колір.
Приклад
Наведені в прикладі графи мають наступний вигляд:
Реалізація алгоритму
Матрицю суміжності графа будемо зберігати в масиві розміром MAX = 1001 (нумерація вершин ведеться від до n \le 1000). Масив зберігає інформацію про колір кожної вершини. Глобальна змінна відповідає за коректність розфарбування: як тільки виявляються дві сусідні вершини, пофарбовані в один і той же колір, ця змінна приймає значення .
#define MAX 1000
int g[MAX][MAX], used[MAX], flag;Функція dfs виконує пошук у глибину. Їй передаються два параметри: поточна вершина та її колір .
void dfs(int v, int color = 1)
{Якщо раніше вже було виявлено випадок, при якому необхідне розфарбування неможливе (flag = 1), виконання функції припиняється.
if (flag) return;Позначаємо вершину кольором color.
used[v] = color;Переглядаємо всі вершини , в які можна перейти з вершини , продовжуючи обхід у глибину.
Якщо вершина ще не була відвідана, запускаємо з неї пошук у глибину, передаючи функції dfs протилежний колір.
Якщо вершина вже була відвідана, перевіряємо коректність розфарбування: якщо вершини і мають однаковий колір, це означає порушення умови двочастковості, і встановлюємо flag = 1.
for (int i = 1; i <= n; i++)
if (g[v][i] == 1)
if (used[i] == 0) dfs(i, 3 - color); else
if (used[v] == used[i]) flag = 1;
}Основний цикл програми. Читаємо кількість вершин та кількість ребер графа. Обнуляємо матрицю суміжності та масив .
while(scanf("%d %d",&n,&l), n)
{
memset(g,0,sizeof(g));
memset(used,0,sizeof(used));Читаємо ребра графа.
for(i = 0; i < l; i++)
{
scanf("%d %d",&a,&b);
g[a][b] = g[b][a] = 1;
}Обнуляємо змінну , і запускаємо пошук у глибину, починаючи з першої вершини, попередньо присвоївши їй колір .
flag = 0;
dfs(1);Залежно від значення змінної виводимо результат.
if (flag) printf("NOT BICOLOURABLE.\n");
else printf("BICOLOURABLE.\n");
}