Двоколірність#3165

Двоколірність (Розбір)

У задачі слід перевірити, чи можна розфарбувати граф у кольори так, щоб будь-які дві сусідні вершини мали різні кольори. Такий граф називається двочастковим.

Якщо здійснити пошук у глибину на графі, то:

Тобто кольори вершин повинні чергуватися за глибиною обходу.

Для розв'язання задачі скористаємось пошуком у глибину. Спочатку всі вершини вважаються невідвіданими і позначаються кольором . У процесі обходу графа будемо розфарбовувати вершини у два кольори: і . Якщо поточна вершина має колір (де 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;

Переглядаємо всі вершини , в які можна перейти з вершини , продовжуючи обхід у глибину.

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