Məsələdə qrafı elə rəngə boyamağın mümkün olub-olmadığını yoxlamaq lazımdır ki, hər hansı iki qonşu təpə fərqli rəngdə olsun. Belə qraf ikitərəfli (двудольный) adlanır.
Əgər qraf üzərində dərinliyinə axtarış həyata keçirsək, onda:
Tutaq ki, birinci təpənin rəngi -dir;
Onda onun bütün qonşuları rənginə malik olmalıdır;
rəngli təpələrin qonşuları yenidən rəngində olmalıdır;
Və beləliklə davam edir...
Yəni təpələrin rəngləri gəzintinin dərinliyi üzrə növbələşməlidir.
Məsələnin həlli üçün dərinliyinə axtarışdan istifadə edəcəyik. Əvvəlcə bütün təpələr ziyarət edilməmiş sayılır və rəngi ilə işarələnir. Qrafı gəzərkən təpələri iki rəngə: və -yə boyayacağıq. Əgər cari təpənin rəngi -dirsə (burada i = 1 və ya ), onda dərinliyinə gəzinti zamanı keçdiyimiz hər növbəti təpəni 3 - i rənginə boyayırıq. Bu zaman hər addımda yoxlayırıq ki, heç bir iki qonşu təpə eyni rəngə boyanmasın.
Misal
Misalda verilmiş qraflar aşağıdakı görünüşə malikdir:
Alqoritmin realizasiyası
Qrafın qonşuluq matrisini MAX = 1001 ölçülü massivində saxlayacağıq (təpələrin nömrələnməsi -dən n \le 1000-ə qədər aparılır). massivi hər təpənin rəngi haqqında məlumatı saxlayır. qlobal dəyişəni boyamanın düzgünlüyünə cavabdehdir: eyni rəngə boyanmış iki qonşu təpə aşkar edildiyi anda bu dəyişən qiymətini alır.
#define MAX 1000
int g[MAX][MAX], used[MAX], flag;dfs funksiyası dərinliyinə axtarışı yerinə yetirir. Ona iki parametr ötürülür: cari təpə və onun rəngi .
void dfs(int v, int color = 1)
{Əgər əvvəllər artıq tələb olunan boyamanın mümkün olmadığı hal aşkar edilibsə (flag = 1), funksiyanın icrası dayandırılır.
if (flag) return;təpəsini color rənginə boyayırıq.
used[v] = color;təpəsindən keçə biləcəyimiz bütün təpələrinə baxırıq, dərinliyinə gəzintini davam etdirərək.
Əgər təpəsi hələ ziyarət edilməyibsə, ondan başlayaraq dərinliyinə axtarışı işə salırıq, dfs funksiyasına əks rəngi ötürərək.
Əgər təpəsi artıq ziyarət edilibsə, boyamanın düzgünlüyünü yoxlayırıq: əgər və təpələri eyni rəngə malikdirsə, bu ikitərəflilik şərtinin pozulması deməkdir, və flag = 1 təyin edirik.
for (int i = 1; i \le= n; i++)
if (g[v][i] == 1)
if (used[i] == 0) dfs(i, 3 - color); else
if (used[v] == used[i]) flag = 1;
}Proqramın əsas dövrü. Qrafın təpələrinin sayı və tillərinin sayı -i oxuyuruq. Qonşuluq matrisini və massivini sıfırlayırıq.
while(scanf("%d %d",&n,&l), n)
{
memset(g,0,sizeof(g));
memset(used,0,sizeof(used));Qrafın tillərini oxuyuruq.
for(i = 0; i < l; i++)
{
scanf("%d %d",&a,&b);
g[a][b] = g[b][a] = 1;
}dəyişənini sıfırlayırıq və dərinliyinə axtarışı birinci təpədən başlayaraq işə salırıq, əvvəlcədən ona rəngini mənimsətdikdən sonra.
flag = 0;
dfs(1);dəyişəninin qiymətindən asılı olaraq nəticəni çap edirik.
if (flag) printf("NOT BICOLOURABLE.\n");
else printf("BICOLOURABLE.\n");
}