Həllin mövcudluq şərtlərinə baxaq. Qrafın hər hissəsində təpə yerləşir. Hər təpənin dərəcəsi -dən az və -dən çox olmamalı olduğuna görə, ümumi tillərin sayı aşağıdakı məhdudiyyətlərə cavab verməlidir:
Əgər bu şərt ödənmirsə, tələb olunan qrafı qurmaq mümkün deyil.
Qrafın qurulmasına keçək. Konstruktiv yanaşmadan istifadə edək. Sol hissənin təpələrini sağ hissənin təpələri ilə dövri sürüşmələr vasitəsilə birləşdirəcəyik.
cur = 0 dəyişənini işə salırıq.
Hər i~(1 \le i \le n) üçün sol hissənin təpəsi ilə sağ hissənin j = i + cur nömrəli təpəsi arasında til əlavə edirik. Əgər bündən çoxdursa, onda onun yerinə j = i + cur - n götürürük, yəni faktiki olaraq moduluna görə indeksasiyadan istifadə edirik. Hər til əlavə edildikdən sonra tillərin sayğacını artırırıq. Əlavə edilmiş tillərin ümumi sayı -ə bərabər olan kimi, alqoritm başa çatır.
cur = cur + 1 artırırıq və -ci addımı təkrarlayırıq.
Beləliklə, hər iterasiyada biz "sürüşdürülmüş" til dəstini əlavə edirik ki, bu da təpələrin dərəcələrinin bərabər paylanmasını təmin edir. Nəticədə hər təpənin dərəcəsi -dən artıq olmur, kifayət qədər sayda iterasiyada isə ən azı -yə çatır.
Misal
Misalda göstərilən qraf aşağıdakı görünüşə malikdir:
Alqoritmin realizasiyası
Testlərin sayı -i oxuyuruq.
scanf("%d", \&tests);
while (tests--)
{Növbəti testin giriş məlumatlarını oxuyuruq.
scanf("%d %d %d %d", \&n, \&m, \&d, \&D);Əgər zəruri bərabərsizliklərin ödənilməməsi səbəbindən qrafı qurmaq mümkün deyilsə, çıxarırıq.
if (n * d > m || n * D < m)
{
printf("-1\n");
continue;
}cur = 0 təyin edirik.
cur = 0;
while (m > 0)
{Dəqiq til qurulana qədər, onları göstərilən alqoritmə görə qururuq.
for (i = 1; i <= n; i++)
{
j = (i + cur) % n;
if (j == 0) j = n;tilini çıxarırıq.
printf("%d %d\n", i, j);
m--;Bütün til qurulan kimi, proqramı başa çatdırırıq.
if (m == 0) break;
}dəyişəninin qiymətini artırırıq.
cur++;
}
}