Skip to content

Commit e4d0519

Browse files
committed
course schedule problem
1 parent ee7cbff commit e4d0519

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
/*
4+
Course Schedule / Topological Sorting Problem
5+
6+
Prerequisite:
7+
Graph theory, Topological sorting, Kahn’s Algorithm (BFS-based approach).
8+
9+
Main Idea:
10+
We are given a set of courses and prerequisite relationships (a → b), meaning
11+
you must complete course 'a' before course 'b'. This forms a Directed Graph.
12+
The task is to determine a valid order of completing all courses — a Topological Order.
13+
14+
Solution:
15+
1. Represent courses as graph nodes (1...n) and prerequisites as directed edges.
16+
2. Compute indegree[] for each node (number of prerequisites).
17+
3. Push all nodes with indegree = 0 (no prerequisites) into a queue.
18+
4. Repeatedly remove a node from the queue:
19+
- Add it to the result order.
20+
- Reduce the indegree of all its neighbors by 1.
21+
- If a neighbor’s indegree becomes 0, push it into the queue.
22+
5. If all nodes are processed → we found a valid order.
23+
If not → there exists a cycle, and it's IMPOSSIBLE to finish all courses.
24+
25+
Why It Works:
26+
Kahn’s Algorithm ensures that each course is taken only when all its prerequisites are done.
27+
If a cycle exists (mutual dependencies), some nodes will never reach indegree 0.
28+
29+
Complexity:
30+
Time : O(n + m) — we visit each node and edge once.
31+
Memory: O(n + m) — for adjacency list and indegree array.
32+
33+
Alternative:
34+
A DFS-based topological sort can also be used with recursion and a stack,
35+
but Kahn’s Algorithm (BFS) is iterative and cycle-detection-friendly.
36+
*/
37+
38+
int32_t main() {
39+
ios::sync_with_stdio(false);
40+
cin.tie(nullptr);
41+
42+
int n, m;
43+
cin >> n >> m;
44+
45+
// Adjacency list representation of the graph
46+
// adj[a] will store all nodes b such that there is an edge a -> b
47+
vector<vector<int>> adj(n + 1);
48+
49+
// indegree[i] = number of prerequisites (incoming edges) for course i
50+
vector<int> indegree(n + 1, 0);
51+
52+
// Reading m prerequisite relations
53+
for (int i = 0; i < m; i++) {
54+
int a, b;
55+
cin >> a >> b;
56+
adj[a].push_back(b); // a must come before b
57+
indegree[b]++; // increase indegree of b
58+
}
59+
60+
// Queue to store all courses with no prerequisites (indegree = 0)
61+
queue<int> q;
62+
63+
for (int i = 1; i <= n; i++) {
64+
if (indegree[i] == 0)
65+
q.push(i); // can be taken first
66+
}
67+
68+
// This will store the valid topological order
69+
vector<int> order;
70+
71+
// Process nodes with no incoming edges
72+
while (!q.empty()) {
73+
int u = q.front();
74+
q.pop();
75+
order.push_back(u);
76+
77+
// Reduce indegree of all neighbors (courses depending on u)
78+
for (int v : adj[u]) {
79+
indegree[v]--;
80+
// If indegree becomes 0, it can now be taken
81+
if (indegree[v] == 0)
82+
q.push(v);
83+
}
84+
}
85+
86+
// If we couldn't include all courses, there’s a cycle → impossible to finish all
87+
if ((int)order.size() != n) {
88+
cout << "IMPOSSIBLE\n";
89+
} else {
90+
// Print valid topological order
91+
for (int x : order)
92+
cout << x << " ";
93+
cout << "\n";
94+
}
95+
96+
return 0;
97+
}

0 commit comments

Comments
 (0)