ამოცანები რომლებიც იხსნება ციკლის პოვნის
ალგორითმით, ტოპოლოგიური დალაგებით,
დეიქსტრას და ბელმან ფორდის
ალგორითმებით
მარიამ გობრონიძე

•
•
•
•

Course Schedule
Course Schedule II
Network Delay Time
Cheapest Flights Within K

სასწავლო კურსების გაანრიგი I
ვთქვათ მოცემულია numCourses რაოდენობის კურსი, რომლებიც გადანომრილია 0-დან
numCourses - 1-მდე. მოცემულია მასივი prerequisites, სადაც თითოეული ელემენტი
prerequisites[i] = [a_i, b_i] მიუთითებს, რომ კურსი a_i მხოლოდ იმ შემთხვევაში შეიძლება
გაიაროთ, თუ ჯერ კურსი b_i უკვე გაქვთ გავლილი.
მაგალითად, წყვილი [0, 1] ნიშნავს, რომ კურსის 0 გასავლელად ჯერ საჭიროა კურსი 1-ის
გავლა.
დააბრუნეთ true, თუ შესაძლებელია ყველა კურსის გავლა. წინააღმდეგ შემთხვევაში
დააბრუნეთ false.

მაგალითი 1:
ვთქვათ: numCourses = 2, prerequisites = [[1, 0]]
შედეგი: true
აღწერა : სულ არსებობს 2 კურსი, რომელიც უნდა გაიაროთ.
იმისათვის, რომ კურსი 1 გაიაროთ, აუცილებელია, რომ ჯერ კურსი 0 გავლილი გქონდეთ.
შესაბამისად, კურსების გავლა შესაძლებელია.

მაგალითი 2:
ვთვათ: numCourses = 2, prerequisites = [[1, 0], [0, 1]]
შედეგი: false
აღწერა : სულ არსებობს 2 კურსი, რომელიც უნდა გაიაროთ.
იმისათვის, რომ კურსი 1 გაიაროთ, აუცილებელია, რომ ჯერ კურსი 0 გაიაროთ,
ხოლო კურსი 0-ის გასავლელად — კურსი 1 უნდა გქონდეთ გავლილი.
ამგვარად, კურსები ციკლურ დამოკიდებულებაში არიან და მათი გავლა შეუძლებელია.

სირთულის შეფასება
დროითი სირთულე: O(V+E);
მეხსიერებითი სირთულე: O(V+E)
V - კურსების რაოდენობა
E - წინაპორობების სიის სიგრძე

სასწავლო კურსების გაანრიგი II
მოცემულია n კურსი, ნუმერაციით 0-დან n-1-მდე და პრერეკვიზიტების სია prerequisites,
სადაც prerequisites[i] = [x, y] ნიშნავს, რომ კურსის x გავლისთვის აუცილებელია
კურსი y წინასწარ იყოს გავლილი.
🔹 თქვენ უნდა დააბრუნოთ კურსების გავლის რიგი (ტოპოლოგიური თანმიმდევრობა),
რომელიც აკმაყოფილებს ყველა პრერეკვიზიტს.
🔹 თუ არსებობს რამდენიმე სწორი თანმიმდევრობა — ნებისმიერის დაბრუნება შეიძლება.
🔹 თუ ვერ ხერხდება კურსების სრულად გავლა (შეიცავს ციკლს) — დააბრუნეთ ცარიელი სია
[].

მაგალითი
Input:
n = 2, prerequisites = [[1, 0]]
Output: [0, 1]
განმარტება : კურსი 1 უნდა გაიაროთ მხოლოდ მას შემდეგ, რაც 0 კურსს გაივლით. სწორი
თანმიმდევრობაა: [0, 1].
Input:
n = 4, prerequisites = [[1, 0], [2, 0], [3, 1], [3, 2]]
Output: [0, 1, 2, 3] ან [0, 2, 1, 3]
განმარტება : კურსი 3 საჭიროებს კურსებს 1 და 2; ხოლო ისინი ორივე საჭიროებენ კურსს 0.

ნაბიჯების აღწერა
1.
2.
3.

4.

გრაფის აგება — მოსაზღვრეობის სიის გამოყენებით.
შემავალი ხარისხების მასივის შექმნა — თითოეული კურსისთვის, რამდენი კურსია
აუცილებელი.
ტოპოლოგიური სორტირება BFS-ით:
○ ყველა კურსი, რომლის in-degree == 0, “დადგება” რიგში.
○ ყოველ ეტაპზე რიგიდან ამოვიღებთ ერთ კურსს და შედეგში დავამატებთ.
○ მეზობელი კურსების in-degree მცირდება, და თუ ის 0 გახდება, რიგში
თავსდება.
ციკლის დადგენა — თუ საბოლოო სიის სიგრძე ნაკლებია n-ზე, გრაფი შეიცავს ციკლს.

სირთულის შეფასება
დროითი სირთულე: O(V+E);
მეხსიერებითი სირთულე: O(V+E)
V - კურსების რაოდენობა
E - წინაპორობების სიის სიგრძე

ამოცანა: Network Delay Time
მოცემულია ქსელი, რომელიც შედგება n რაოდენობის წვეროსგან (nodes), რომლებიც
დანომრილია 1-იდან n-ის ჩათვლით.
ასევე მოცემულია მიმართული წიბოების სია times, სადაც:
●

times[i] = (u_i, v_i, w_i) ნიშნავს, რომ u_i-დან v_i-მდე სიგნალის
გაგზავნას სჭირდება w_i დრო.

სიგნალს ვაგზავნით წინასწარ დასახელებული კონკრეტული k წვერიდან.
უნდა დავაბრუნოთ მინიმალური დრო, რომელიც დასჭირდება სიგნალს, რათა მიაღწიოს
ყველა დანარჩენ წვერომდე.
თუ არსებობს წვერი, რომელზეც სიგნალი ვერ მიაღწევს, დააბრუნეთ -1.

მაგალითი

input: [[2,1,1], [2,3,1], [3,4,1]] n=4, k=2
output: 2

მაგალითი
input: [[1,2,1]] n=2, k=1
output: 1
input: [[1,2,1]] n=2, k=2
output: -1

ნაბიჯები
•

გრაფის აგება – გრაფის წარმოდგენა მოსაზღვრეობის სიად.

•

ჰიპის ინიციალიზაცია საწყისი კვანძით.

•

მოსაზღვრე კვანძების გადამოწმება მინიმალური წონის მიხედვით.

•

მანძილების განახლება მხოლოდ იმ კვანძებისთვის, რომლებთანაც ჯერ არ
მივსულვართ.

•

დაბრუნება – თუ ყველა კვანძს მივწვდით, ვაბრუნებთ მაქსიმალურ დისტანციას,
თუ არა – -1.

ალგორითმის სირთულე
დროითი სირთულე: O(E * log N)
მეხსიერებითი სირთულე: O(E + N)
სადაც E – წიბოების რაოდენობა, N – კვანძების რაოდენობა.

ყველაზე იაფი ავიაბილეთი k გაჩერებით
მოცემულია n ქალაქი, რომლებიც ერთმანეთთან დაკავშირებულია გარკვეული
რაოდენობის ავიარეისებით. დავუშვათ flights სია შეიცავს ინფორმაციას
ფრენების შესახებ, სადაც flights[i] = [fromᵢ, toᵢ, priceᵢ] აღნიშნავს, რომ
არსებობს ავიარეისი ქალაქიდან fromᵢ ქალაქში toᵢ, ბილეთის ფასით priceᵢ.
ასევე მოცემულია სამი მთელი რიცხვი: src (საწყისი ქალაქი), dst (სამიზნე ქალაქი) და
k (გაჩერებების მაქსიმალური რაოდენობა).
თქვენი ამოცანაა დააბრუნოთ ყველაზე იაფი ბილეთის ფასი src-დან dst-ში
გადაადგილებისთვის, რომლის დროსაც მაქსიმუმ k გაჩერებაა დაშვებული.
თუ ასეთი მარშრუტი არ არსებობს, უნდა დააბრუნოთ -1.

მაგალითი

input: n=4, flights: [[0, 1, 100], [1, 2, 100], [2, 0, 100],
[1, 3, 600], [2, 3, 200]], src =0, dst = 3, k = 1
output = 700

განმარტება:
ყველაზე იაფი მარშრუტი ქალაქიდან 0 ქალაქში 3 ერთი გაჩერებით არის:
0 → 1 → 3, ჯამური ღირებულება: 100 + 600 = 700.
მარშრუტი 0 → 1 → 2 → 3 იაფია (400), მაგრამ შეიცავს 2 გაჩერებას – ეს დაშვებულზე მეტია,
შესაბამისად არ ითვლება.

ნაბიჯები
1.
2.
3.

4.

5.

ინიციალიზაცია : ვქმნით prices სიას, სადაც ყველა ქალაქის ფასი ინიციალიზდება ∞ით (უსასრულობით), გარდა საწყისი (src) ქალაქისა, რომლის ფასი არის 0.
იტერაცია k + 1-ჯერ: რადგან k გაჩერება გულისხმობს k + 1 ფრენას მაქსიმუმ,
range(k + 1) ციკლი უზრუნველყოფს ამდენჯერ გრაფის განახლებას.
ფრენების გადამოწმება : თითოეულ იტერაციაზე (ანუ თითოეულ შესაძლო გაჩერებაზე),
შევადარებთ თითოეული ფრენის დასაწყის და საბოლოო წერტილზე არსებულ ფასებს და
ვცდილობთ შევამციროთ საბოლოო წერტილის ფასი.
შუალედური მასივის გამოყენება (tmpPrices): რათა ერთდროულად არ მოხდეს
ცვლილებები მიმდინარე ციკლში, ფასებს ვანახლებთ tmpPrices მასივში და შემდეგ
ვანაცვლებთ prices-ით.
შედეგის დაბრუნება : თუ საბოლოოდ სამიზნე (dst) ქალაქის ფასი კვლავ ∞-ია –
ნიშნავს, რომ ვერ მივედით მასთან k გაჩერებით – დააბრუნე -1. წინააღმდეგ
შემთხვევაში დაბრუნდი prices[dst].

სირთულის შეფასება
დროითი სირთულე : O(k * E)
●
●

სადაც k – გაჩერებების რაოდენობა (ანუ იტერაციების რიცხვი),
ხოლო E – ფრენების რაოდენობა (სიის flights სიგრძე).

მეხსიერებითი სირთულე : O(n)
საჭირო მხოლოდ ორი ერთგანზომილებიანი მასივი prices და tmpPrices, ზომით n
(ქალაქების რაოდენობა).

გმადლობთ ყურადღებისთვის!

