bool canFinish(int n, vector<vector<int>>& prerequisites) {
vector<vector<int>> adj(n);
for (auto& p : prerequisites) adj[p[1]].push_back(p[0]);
unordered_set<int> path;
function<bool(int)> hasCycleFrom = [&](int node) -> bool {
if (path.count(node)) return true;
path.insert(node);
for (int next : adj[node]) {
if (hasCycleFrom(next)) return true;
}
path.erase(node);
return false;
};
for (int c = 0; c < n; c++) {
path.clear();
if (hasCycleFrom(c)) return false;
}
return true;
}
public boolean canFinish(int n, int[][] prerequisites) {
List<List<Integer>> adj = new ArrayList<>();
for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
for (int[] p : prerequisites) adj.get(p[1]).add(p[0]);
for (int c = 0; c < n; c++) {
if (hasCycleFrom(c, new HashSet<>(), adj)) return false;
}
return true;
}
private boolean hasCycleFrom(int node, Set<Integer> path, List<List<Integer>> adj) {
if (path.contains(node)) return true;
path.add(node);
for (int next : adj.get(node)) {
if (hasCycleFrom(next, path, adj)) return true;
}
path.remove(node);
return false;
}
def can_finish(n: int, prerequisites: list[list[int]]) -> bool:
adj = [[] for _ in range(n)]
for course, pre in prerequisites: adj[pre].append(course)
def has_cycle_from(node: int, path: set[int]) -> bool:
if node in path: return True
path.add(node)
for nxt in adj[node]:
if has_cycle_from(nxt, path): return True
path.remove(node)
return False
for c in range(n):
if has_cycle_from(c, set()): return False
return True
function canFinish(n: number, prerequisites: number[][]): boolean {
const adj: number[][] = Array.from({ length: n }, () => []);
for (const [course, pre] of prerequisites) adj[pre].push(course);
const hasCycleFrom = (node: number, path: Set<number>): boolean => {
if (path.has(node)) return true;
path.add(node);
for (const next of adj[node]) {
if (hasCycleFrom(next, path)) return true;
}
path.delete(node);
return false;
};
for (let c = 0; c < n; c++) {
if (hasCycleFrom(c, new Set())) return false;
}
return true;
}
bool canFinish(int n, vector<vector<int>>& prerequisites) {
vector<vector<int>> adj(n);
for (auto& p : prerequisites) adj[p[1]].push_back(p[0]);
vector<int> state(n, 0); // 0 = new, 1 = visiting, 2 = done
function<bool(int)> hasCycle = [&](int u) -> bool {
if (state[u] == 1) return true;
if (state[u] == 2) return false;
state[u] = 1;
for (int v : adj[u]) if (hasCycle(v)) return true;
state[u] = 2;
return false;
};
for (int u = 0; u < n; u++) if (hasCycle(u)) return false;
return true;
}
public boolean canFinish(int n, int[][] prerequisites) {
List<List<Integer>> adj = new ArrayList<>();
for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
for (int[] p : prerequisites) adj.get(p[1]).add(p[0]);
int[] state = new int[n]; // 0 = new, 1 = visiting, 2 = done
for (int u = 0; u < n; u++) if (hasCycle(u, adj, state)) return false;
return true;
}
private boolean hasCycle(int u, List<List<Integer>> adj, int[] state) {
if (state[u] == 1) return true;
if (state[u] == 2) return false;
state[u] = 1;
for (int v : adj.get(u)) if (hasCycle(v, adj, state)) return true;
state[u] = 2;
return false;
}
def can_finish(n: int, prerequisites: list[list[int]]) -> bool:
adj = [[] for _ in range(n)]
for course, pre in prerequisites: adj[pre].append(course)
state = [0] * n # 0 = new, 1 = visiting, 2 = done
def has_cycle(u: int) -> bool:
if state[u] == 1: return True
if state[u] == 2: return False
state[u] = 1
for v in adj[u]:
if has_cycle(v): return True
state[u] = 2
return False
for u in range(n):
if has_cycle(u): return False
return True
function canFinish(n: number, prerequisites: number[][]): boolean {
const adj: number[][] = Array.from({ length: n }, () => []);
for (const [course, pre] of prerequisites) adj[pre].push(course);
const state = new Array<number>(n).fill(0); // 0 = new, 1 = visiting, 2 = done
const hasCycle = (u: number): boolean => {
if (state[u] === 1) return true;
if (state[u] === 2) return false;
state[u] = 1;
for (const v of adj[u]) if (hasCycle(v)) return true;
state[u] = 2;
return false;
};
for (let u = 0; u < n; u++) if (hasCycle(u)) return false;
return true;
}
bool canFinish(int n, vector<vector<int>>& prerequisites) {
vector<vector<int>> adj(n);
vector<int> indegree(n, 0);
for (auto& p : prerequisites) {
adj[p[1]].push_back(p[0]);
indegree[p[0]]++;
}
queue<int> q;
for (int i = 0; i < n; i++) if (indegree[i] == 0) q.push(i);
int taken = 0;
while (!q.empty()) {
int u = q.front(); q.pop();
taken++;
for (int v : adj[u]) {
if (--indegree[v] == 0) q.push(v);
}
}
return taken == n;
}
public boolean canFinish(int n, int[][] prerequisites) {
List<List<Integer>> adj = new ArrayList<>();
for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
int[] indegree = new int[n];
for (int[] p : prerequisites) {
adj.get(p[1]).add(p[0]);
indegree[p[0]]++;
}
Deque<Integer> queue = new ArrayDeque<>();
for (int i = 0; i < n; i++) if (indegree[i] == 0) queue.add(i);
int taken = 0;
while (!queue.isEmpty()) {
int u = queue.poll();
taken++;
for (int v : adj.get(u)) {
if (--indegree[v] == 0) queue.add(v);
}
}
return taken == n;
}
def can_finish(n: int, prerequisites: list[list[int]]) -> bool:
adj = [[] for _ in range(n)]
indegree = [0] * n
for course, pre in prerequisites:
adj[pre].append(course)
indegree[course] += 1
queue = deque()
for i in range(n):
if indegree[i] == 0: queue.append(i)
taken = 0
while queue:
u = queue.popleft()
taken += 1
for v in adj[u]:
indegree[v] -= 1
if indegree[v] == 0: queue.append(v)
return taken == n
function canFinish(n: number, prerequisites: number[][]): boolean {
const adj: number[][] = Array.from({ length: n }, () => []);
const indegree = new Array<number>(n).fill(0);
for (const [course, pre] of prerequisites) {
adj[pre].push(course);
indegree[course]++;
}
const queue: number[] = [];
for (let i = 0; i < n; i++) if (indegree[i] === 0) queue.push(i);
let taken = 0;
while (queue.length > 0) {
const u = queue.shift()!;
taken++;
for (const v of adj[u]) {
if (--indegree[v] === 0) queue.push(v);
}
}
return taken === n;
}
bool canFinish(int n, vector<vector<int>>& prerequisites) {
if (n <= 0) return true;
int m = prerequisites.size();
vector<int> head(n + 1, 0);
vector<int> indegree(n, 0);
for (int i = 0; i < m; i++) {
int course = prerequisites[i][0], pre = prerequisites[i][1];
if (course < 0 || course >= n || pre < 0 || pre >= n) return false;
head[pre + 1]++;
indegree[course]++;
}
for (int i = 0; i < n; i++) head[i + 1] += head[i];
vector<int> to(m);
vector<int> fill(head.begin(), head.begin() + n);
for (int i = 0; i < m; i++) to[fill[prerequisites[i][1]]++] = prerequisites[i][0];
vector<int> queue(n);
int qh = 0, qt = 0;
for (int i = 0; i < n; i++) if (indegree[i] == 0) queue[qt++] = i;
while (qh < qt) {
int u = queue[qh++];
for (int e = head[u]; e < head[u + 1]; e++) {
if (--indegree[to[e]] == 0) queue[qt++] = to[e];
}
}
return qt == n;
}
public boolean canFinish(int n, int[][] prerequisites) {
if (n <= 0) return true;
int m = prerequisites.length;
int[] head = new int[n + 1];
int[] indegree = new int[n];
for (int i = 0; i < m; i++) {
int course = prerequisites[i][0], pre = prerequisites[i][1];
if (course < 0 || course >= n || pre < 0 || pre >= n) return false;
head[pre + 1]++;
indegree[course]++;
}
for (int i = 0; i < n; i++) head[i + 1] += head[i];
int[] to = new int[m];
int[] fill = Arrays.copyOf(head, n);
for (int i = 0; i < m; i++) to[fill[prerequisites[i][1]]++] = prerequisites[i][0];
int[] queue = new int[n];
int qh = 0, qt = 0;
for (int i = 0; i < n; i++) if (indegree[i] == 0) queue[qt++] = i;
while (qh < qt) {
int u = queue[qh++];
for (int e = head[u]; e < head[u + 1]; e++) {
if (--indegree[to[e]] == 0) queue[qt++] = to[e];
}
}
return qt == n;
}
def can_finish(n: int, prerequisites: list[list[int]]) -> bool:
if n <= 0: return True
m = len(prerequisites)
head = [0] * (n + 1)
indegree = [0] * n
for i in range(m):
course, pre = prerequisites[i]
if not (0 <= course < n and 0 <= pre < n): return False
head[pre + 1] += 1
indegree[course] += 1
for i in range(n): head[i + 1] += head[i]
to = [0] * m
fill = head[:n]
for i in range(m):
to[fill[prerequisites[i][1]]] = prerequisites[i][0]
fill[prerequisites[i][1]] += 1
queue = [0] * n
qh = qt = 0
for i in range(n):
if indegree[i] == 0:
queue[qt] = i
qt += 1
while qh < qt:
u = queue[qh]
qh += 1
for e in range(head[u], head[u + 1]):
indegree[to[e]] -= 1
if indegree[to[e]] == 0:
queue[qt] = to[e]
qt += 1
return qt == n
function canFinish(n: number, prerequisites: number[][]): boolean {
if (n <= 0) return true;
const m = prerequisites.length;
const head = new Int32Array(n + 1);
const indegree = new Int32Array(n);
for (let i = 0; i < m; i++) {
const [course, pre] = prerequisites[i];
if (course < 0 || course >= n || pre < 0 || pre >= n) return false;
head[pre + 1]++;
indegree[course]++;
}
for (let i = 0; i < n; i++) head[i + 1] += head[i];
const to = new Int32Array(m);
const fill = head.slice(0, n);
for (let i = 0; i < m; i++) to[fill[prerequisites[i][1]]++] = prerequisites[i][0];
const queue = new Int32Array(n);
let qh = 0, qt = 0;
for (let i = 0; i < n; i++) if (indegree[i] === 0) queue[qt++] = i;
while (qh < qt) {
const u = queue[qh++];
for (let e = head[u]; e < head[u + 1]; e++) {
if (--indegree[to[e]] === 0) queue[qt++] = to[e];
}
}
return qt === n;
}